leetcode No.16 3Sum Closest(最接近的三數之和)

題幹:

file

效果:

file

思路:

這道題跟No.15很像,就是要找三數之和,但15是找三數之和爲0,這題是找離target最近的和。

首先我們得排序,因爲調用默認排序的時間複雜度是O(nlogn),而這道題暴力遍歷是O(n^3),想處理三個數,至少也得是O(n^2)的複雜度,所以先給他排個序對時間複雜度不會有大的影響。

從小到大排完序後,前兩個從前往後取,第三個從最後位置往前取,這樣就有一個好處,我們把這三個數加起來,如果它超過target,那顯然是因爲數不夠大,那就讓中間那個數往後移動,如果小於target,那麼就往前移動第三個數。

每次移動完後,記錄最小的差值,最後循環結束返回最小的差值就行。

這裏我一開始並沒有bug free,因爲三數之和與target值有兩種接近方式,一種是>,一種是<,所以我就設了兩個標識變量,哪個更接近就返回哪個,但是發現min_value是整數的最小值,而如果對它取絕對值,它就會溢出,然後變成1,而MAX_VALUE取反不會溢出,所以你們會看到我最後return時並沒有用abs方式。

代碼:

import java.util.Arrays;

class Solution {
    public int threeSumClosest(int[] nums, int target) {
        //先排序
        Arrays.sort(nums);
        //初始化最接近的值
        int closePlusMin=Integer.MAX_VALUE;
        int closeMinusMax = Integer.MIN_VALUE;
        for(int i=0;i<nums.length-2;i++){
            if(i==0||i>0&&nums[i-1]!=nums[i]){
                int low = i+1;
                int high = nums.length-1;
                while(low<high){
                    int sum = nums[low]+nums[high]+nums[i];
                    if(sum==target){
                        return target;
                    }
                    else if(sum<target){
                        low++;
                    }
                    else{
                        high--;
                    }
                    if(sum-target>0){
                        closePlusMin = Math.min(closePlusMin,sum-target);
                    }
                    else{
                        closeMinusMax = Math.max(closeMinusMax,sum-target);
                    }
                }
            }
        }
        return -closePlusMin>closeMinusMax?target+closePlusMin:target+closeMinusMax;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章