题目描述
给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。
样例描述
输入:nums = [-1,2,1,-4], target = 1
输出:2
解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。
思路
- 双指针。本题与下面这题类似
Leetcode–Java–15. 三数之和
双指针类型的题要求有序,一般先做排序。不同的是,不需要去重。 因为这题求的不是方案数,即使有的方案使得结果相同,也没影响。 - 由于退出while循环时可能是由于j < k - 1或者s < target 两种情况。如果因为j < k - 1退出循环,就判断第k项的累加和与target的差值。 但还得判断如果因为s < target退出的,k - 1这项的累加和与target 的差值是否会更小。
优化后的方法:
- 不分情况。直接顺次枚举,通过不断地动态调整指针的位置来使得临时和s尽量接近target。
2.固定一个指针i,让j从左边开始,k从右边开始,不断向中间靠拢,同时判断临时和s与target的关系,然后调整指针。
代码
class Solution {
public int threeSumClosest(int[] nums, int target) {
int len = nums.length;
Arrays.sort(nums);
int res = 99999;
for (int i = 0; i < len; i ++ ) {
for (int j = i + 1, k = len -1; j < k; j ++ ) {
while (j < k - 1 && nums[i] + nums[j] + nums[k - 1] >= target ) k --;
int s = nums[i] + nums[j] + nums[k];
if (Math.abs(s - target) < Math.abs(res - target)){
res = s;
}
//如果是由于<target ,要看k - 1项累加的和与target的差值是否更小
if (j < k - 1) {
s = nums[i] + nums[j] + nums[k - 1];
if (Math.abs(s - target) < Math.abs(res - target)) {
res = s;
}
}
}
}
return res;
}
}
优化后方法
class Solution {
public int threeSumClosest(int[] nums, int target) {
Arrays.sort(nums);
int res = 99999;
int len = nums.length;
for (int i = 0; i < len - 2; i ++) {
//左右指针
int l = i + 1, r = len - 1;
while (l < r) {
int s = nums[i] + nums[l] + nums[r];
//差值更小就更新
if (Math.abs(s - target) < Math.abs(res - target)){
res = s;
}
if (s < target)
l ++;
else if (s > target)
r --;
else return s;
}
}
return res;
}
}