题干
给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数,使它们的和与 target 最接近。
返回这三个数的和。
假定每组输入只存在恰好一个解。
示例
示例1
输入:nums = [-1,2,1,-4], target = 1
输出:2
解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。
示例2
输入:nums = [0,0,0], target = 1
输出:0
题解
排序+双指针
时间复杂度:O(N^2) 空间复杂度:O(logN)
思路及解法
这道题和第15题三数之和非常像,依旧是利用排序+双指针的方法。给数组排序之后,就可以通过对比(三个数之和-target)与0的大小,利用数组有序这一特性,来控制指针移动。
目标是找到最接近,所以是求差值绝对值最小的组合。Math.abs()的方法作用是求绝对值。
数组排好序后,设第一个数为a,第二个数为b,第三个数为c。第一个数固定,我们在第一个数后面枚举b和c。
- if a+b+c > target ,第三个指针左移
- if a+b+c < target,第二个指针右移
- if a+b+c = target 直接输出
代码实现
class Solution {
public int threeSumClosest(int[] nums, int target) {
Arrays.sort(nums);
int len = nums.length;
int cloestNum = nums[0] + nums[1] + nums[len-1]; //初始化最接近的三个数的和
for(int i = 0; i < len -2 ; i++){
int L = i+1;
int R = len-1;
while(L < R){
int currSum = nums[i] + nums[L] + nums[R]; //当前循环中三个值的和currSum
if( currSum == target) return currSum; //正好是这个值
cloestNum = Math.abs(currSum - target) > Math.abs(cloestNum - target)? cloestNum : currSum;
//利用三目运算符,判断当前的三个数是否是最接近解,来更新cloestNum
if (currSum > target) R--;
if (currSum < target) L++;
}
}
return cloestNum;
}
}
归纳与总结
- 排序后的数组,可以很好的用来控制指针移动,进而减低时间复杂度。
- 还是要好好注意一下数组越界的问题,注意变量的声明位置。循环里定义的变量循环结束后生命周期就结束了。