问题描述:
Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution.
For example, given array S = {-1 2 1 -4}, and target = 1.
The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
题目解析:
一上来先想起最蠢的办法,brute force三层循环。
class Solution {
public int threeSumClosest(int[] nums, int target) {
int diff = Integer.MAX_VALUE;
int value = 0;
for(int i=0; i<nums.length; i++){
for(int j=i+1; j < nums.length; j++){
for(int k=j+1; k < nums.length; k++){
if((Math.abs(nums[i]+nums[j]+nums[k]-target))<diff){
value = nums[i]+nums[j]+nums[k];
diff = Math.abs(value-target);
}
}
}
}
return value;
}
}
经典解答:
后来看了解答,发现这种问题需要先排序。
将三个数的index分别标记为fix,middle,last。
每次遍历先固定第一个数;然后任务就简化为在后面数组中,取两个数,使a+b+c和target的difference绝对值最小的组合。
将b和c固定在nums[a+1:nums.length]这个区间的头尾。保持b<c,如果差值大于0说明需要一个小一点的数字,所以把c向左移;如果小于0说明需要大的,把b向右。
复杂度为O(n^2)
class Solution {
public int threeSumClosest(int[] nums, int target) {
int diff = Integer.MAX_VALUE;
int value = 0;
int fix, middle, last = 0;
Arrays.sort(nums);
for(fix=0; fix<nums.length; fix++){
middle = fix + 1;
last = nums.length - 1;
while(middle < last){
if(diff > Math.abs(nums[fix]+nums[middle]+nums[last]-target)){
value = nums[fix]+nums[middle]+nums[last];
diff = Math.abs(nums[fix]+nums[middle]+nums[last]-target);
}
if(nums[fix]+nums[middle]+nums[last]-target > 0){
last --;
}
else if(nums[fix]+nums[middle]+nums[last]-target < 0){
middle ++;
}
else{
return value;
}
}
}
return value;
}
}
1. 为什么这种方法不会遗漏?
2. 选择fix中间的数字会怎样?也可以的,只不过while的判断条件变成了左边<中间&&中间<右边。
3. 思路的来源?