题意:给定n个整数的数组S,找出S中最接近目标的3个数的和,返回和。
思路:由于题意只需要求和,不需要返回的元素的位置,那么可以先对数组排序,再求和
优化: 1、已经找到3个元素的和为target,停止程序;
2、i : 0->length-3, j: 0->length-2, index = binarySearch(j+1, length,target - array[i] - array[j]),避免元素被重复计算多次,如数组【1,3,4,6】,目标为9,如果4被计算多次会得到9实际值为8,向后搜索,认为小于j的搜索域已取得最优值,只需向后搜索得到更优值。如果第三个值的下标为j+1说明j的循环需要结束。
public int threeSumClosest(int[] nums, int target) {
Arrays.sort(nums);
int twoSum, delta = Integer.MAX_VALUE;//minus and plus
for(int i = 0; i < nums.length - 2; i++){
for(int j = i + 1; j < nums.length - 1; j++){//the last but one:gurantee j > i
twoSum = nums[i] + nums[j];
int last = target - twoSum;
int index = Arrays.binarySearch(nums, j+1, nums.length, last);
if(index >= 0){ //avoid repetitivly add a num
return target;
}
int insertionPoint = -(index + 1);
/*if(insertionPoint < i){
if(insertionPoint == 0){
}
break; //already searched
}*/
int temp;
/* if(insertionPoint <= j || (insertionPoint - j == 1 && insertionPoint != nums.length)){ //search forward never push back
temp = twoSum + nums[j+1] - target; //plus
if(temp < ((delta > 0) ? delta : -delta)){
delta = temp;
}
break;
}*/
if(insertionPoint == j+1){ //insertionPoint >= j+1
temp = twoSum + nums[j+1] - target; //plus
if(temp < ((delta > 0) ? delta : -delta)){
delta = temp;
}
break;
}
/* if(insertionPoint - j >= 2){//minus
temp = target - twoSum - nums[insertionPoint-1];
if(temp < ((delta > 0) ? delta : -delta)){
delta = -temp;
}
}*/
temp = target - twoSum - nums[insertionPoint-1];
if(temp < ((delta > 0) ? delta : -delta)){
delta = -temp;
}
if(insertionPoint == nums.length){
continue;
}
temp = twoSum + nums[insertionPoint] - target;//the larger
if(temp < ((delta > 0) ? delta : -delta)){
delta = temp; //plus
}
}
}
return target + delta;
}