# 最接近的三数之和
给你一个长度为 n
的整数数组 nums
和 一个目标值 target
。请你从 nums
中选出三个整数,使它们的和与 target
最接近
返回这三个数的和
假定每组输入只存在恰好一个解
提示:
3 <= nums.length <= 1000
-1000 <= nums[i] <= 1000
-104 <= target <= 104
# 测试用例
用例1:
- 输入:
nums = [-1,2,1,-4], target = 1
- 输出:
2
- 解释:与
target
最接近的和是2 (-1 + 2 + 1 = 2)
用例2
- 输入:
nums = [0,0,0], target = 1
- 输出:
0
# 思路
三数之和要先枚举第一个数,把问题转为求另外两个数 —— 双指针
三个数的和s
与target
取绝对值 —— 绝对值最小,越接近 —— 用diffMin
维护|s-target|
的最小值
- 如果
s - target = 0
,则答案就是s
,直接返回 - 如果
s - target > 0
, 判断此时的s - target
是否小于diffMin
, 如果小于了,就证明找到了一个更接近target
的和,更新diffMin
, 同时右指针减1 - 如果
s - target < 0
, 判断此时的target - s
是否小于diffMin
, 如果小于了,就证明找到了一个更接近target
的和,更新diffMin
, 同时左指针加1
# 代码实现
/**
* @param {number[]} nums
* @param {number} target
* @return {number}
*/
var threeSumClosest = function(nums, target) {
// 最接近
// 三数之和先枚举第一个数,把问题转为求另外两个数 —— 双指针
// 三个数的和s与target取绝对值 —— 绝对值最小,越接近 —— 用diffMin维护|s-target|的最小值
// 1. 如果s - target = 0,则答案就是s,直接返回
// 2. 如果s - target > 0, 判断此时的s - target是否小于diffMin, 如果小于了,就证明找到了一个更接近target的和,更新diffMin, 同时右指针减1
// 3. 如果s - target < 0, 判断此时的target - s是否小于diffMin, 如果小于了,就证明找到了一个更接近target的和,更新diffMin, 同时左指针加1
// 排序
nums.sort((a, b) => a - b);
// 记录结果
let ans = 0;
// 记录和
let s = 0;
// 维护|s-target|
let diffMin = Number.MAX_SAFE_INTEGER;
for(let i = 0; i < nums.length - 2; i ++){
const cur = nums[i];
let l = i + 1;
let r = nums.length - 1;
// 去重优化
if(i > 0 && nums[i] === nums[i - 1]){
continue;
}
// 和最大值优化 —— 但要判断是否是最优解
let sMax = cur + nums[i + 1] + nums[i + 2];
if(sMax > target){
if(sMax - target < diffMin){
ans = sMax;
}
break;
}
// 开始枚举
while(l < r){
s = cur + nums[l] + nums[r];
if(s - target === 0){
ans = s;
return ans;
}
else if(s - target > 0){
// 是否更新diffMin
if(s - target < diffMin){
diffMin = s - target;
ans = s;
}
// 去重判断
while(i < r && nums[r] === nums[r - 1]){
r --;
}
r --;
}
else{
if(target - s < diffMin){
diffMin = target - s;
ans = s;
}
while(l < r && nums[l] === nums[l + 1]){
l ++;
}
l ++;
}
}
}
return ans;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75