题目:
给出含有n个整数的数组s,找出s中和加起来的和最接近给定的目标值的三个整数。返回这三个整数的和。你可以假设每个输入都只有唯一解。
例如,给定的整数 S = {-1 2 1 -4}, 目标值 = 1.↵↵ 最接近目标值的和为 2. (-1 + 2 + 1 = 2).
思路:
整体分为两步。第一步:对数组进行排序。
第二步:使用内外层循环。因为是是三个数字和。因此,外层循环从左至右,一次取出num[i],作为三个数中的其中的一个数。内层循环是三个数中的其它两个数,第二个数left,指向i+1,根据具体情况进行依次向右移动。第三个数是right,指向num.length-1(也就是数组中的最后一个数),根据具体情况依次向左边移动。
求和sum = num[i] + num[left] + num[right] 并且与target进行比较,判断之间的数值差距。
- 当sum = target 时:此时两者差距最小,直接返回sum即可。
- 当sum < target 时:此时说明sum偏大,将right向左边移动,使sum变小一点。
- 当sum > target 时: 此时说明sum偏小,将left向右边移动,使sum变大一点。
当left = right ,说明内层循环结束,此时返回到外层循环,进行新一轮的循环。
代码:
package com.company;
import java.util.Arrays;
public class TestNo14 {
public static void main(String[] args) {
TestNo14 t = new TestNo14();
int[] a = {-1,2,1,-4};
System.out.println(t.threeSumClosest(a,1));
}
public int threeSumClosest(int[] num, int target) {
Arrays.sort(num);//对数组进行排序
int result = num[0] + num[1] + num[num.length-1];//
for(int i = 0;i<num.length;i++){
int left = i+1;
int right = num.length-1;
while (left<right){
int sum = num[i]+num[left]+num[right];
if(sum == target){ //三数之和等于target时距离最近
return target;
}
else{
int dis = Math.abs(sum-target);
int temp = Math.abs(result-target);//result是固定的第一、第二以及最后一个数的和
if(dis < temp){ //最开始dis和temp是相等的,随着循环,新的和比上次更接近target
result = sum;
}
if(sum > target){//三数和sum 比 target 大,right 左移动减小sum
right--;
}
else{//sum 比 target小,右移动增加和
left++;
}
}
}
}
return result;
}
}