題幹:
效果:
思路:
這道題跟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;
}
}