1. 程式人生 > >3Sum Closest

3Sum Closest

[] 代碼 中大 態度 時間 大於 又一 得到 target

描述

給定一個n個整數的數組SS中找到三個整數,使得總和最接近給定數量的目標。返回三個整數的和。你可以假設每個輸入都只有一個解決方案。

    例如,給定數組S = {-1 2 1 -4},target = 1。

    最接近目標的總和是2.(-1 + 2 + 1 = 2)。

解決方案

和上次做的三個數和為0那個題很像,所以首先要想到的當然就是給這個無序數組排序,這樣能降低之後的匹配過程的復雜度。

我又一次本著先做對後看事件復雜度的態度,先按照最傳統的方法做出來了,驚喜的是,通過了,雖然時間復雜度還是很高,下面是我寫的方法:

public int threeSumClosest(int[] nums, int target) {
        Arrays.sort(nums);
        int distance = Math.abs(target-(nums[0]+nums[1]+nums[2]));
        int sum = nums[0]+nums[1]+nums[2];
        for(int i=0; i<nums.length-2;i++){
            if(i == 0 || (i > 0 && nums[i] != nums[i-1])){
                for(int j=i+1; j<nums.length-1; j++){
                    if(j == (i+1) || (j > (i+1) && nums[j] != nums[j-1])){
                        for(int n=j+1; n<nums.length; n++){
                            if((n == (j+1) || (n > (j+1) && nums[n] != nums[n-1])) && (distance>Math.abs(target-(nums[i]+nums[j]+nums[n])))){
                                distance = Math.abs(target-(nums[i]+nums[j]+nums[n]));
                                sum = nums[i]+nums[j]+nums[n];
                            }
                        }
                    }
                }
            }
        }
        return sum;
    }

然後看了討論區中大神們做的,很厲害,其方法還是利用之前那個從兩邊趨近中間的方法,思想如下:

1、先定義第一個數的位置,然後再以第一個數右邊一位的數為最左數,以最後一位數為最右數。

2、把第一個數,最左數和最右數這三個數加和。

3、如果此時三個數的和大於目標數,那麽說明最右數過大,那麽最右數向左移動一位。重復步驟2。

4、如果三個數和小於目標數,那麽說明最左數過小,那麽最左數右移動一位。重復步驟2。

5、在進行2/3/4步驟同時,比較最短距離和記錄三個數的和,以便最後得到正確結果並返回。

具體代碼如下:

public int threeSumClosest1(int[] num, int target) {
        int result = num[0] + num[1] + num[num.length - 1];
        Arrays.sort(num);
        for (int i = 0; i < num.length - 2; i++) {
            int start = i + 1, end = num.length - 1;
            while (start < end) {
                int sum = num[i] + num[start] + num[end];
                //如果此時三個數和大於target,說明最大數過大(即num[end]過大),那麽就要減小大數,否則增大小的數(即num[start]過小)
                if (sum > target) {
                    end--;
                } else {
                    start++;
                }
                if (Math.abs(sum - target) < Math.abs(result - target)) {
                    result = sum;
                }
            }
        }
        return result;
    }

  

3Sum Closest