最接近的三数之和
给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数,使它们的和与 target 最接近。
返回这三个数的和。
假定每组输入只存在恰好一个解。
方法一:排序+双指针
1.1 思路分析
这道题是从三数之和基础上扩展来的,只需要将三数之和的思路稍加修改即可。
这里我们定义一个ans保存最终结果,定义一个dsp保存当前三数和sum与target间的距离,如果出现更小的,则更新dsp和ans.
具体过程如下:
- 先排序,用来去重
- 两层循环:外层first + 内存两个指针second,third
2.1 跳过重复
2.2 进入内层循环
判断sum==target, 如果成立即可返回sum
如果sum > target,判断差值是否最小,更新,third前移
如果sum < target,判断差值是否最小,更新,third后移
1.2 代码实现
func threeSumClosest(nums []int, target int) int {
n := len(nums)
ans := 0
// 计算三数的和,与target比较,不断逼近target
dsp := math.MaxInt32
sort.Ints(nums)
for first:=0; first<n-2; first++{
if first>0 && nums[first] == nums[first-1]{
continue
}
second, third := first+1, n-1
for second < third{
sum := nums[first]+nums[second]+nums[third]
if sum ==target{
return sum
}else if sum > target{
d := sum - target
if d < dsp{
ans = sum
dsp = d
}
for second < third && nums[third] == nums[third-1]{
third--
}
third--
}else{
d := target - sum
if d < dsp{
ans = sum
dsp = d
}
for second < third && nums[second] == nums[second+1]{
second++
}
second++
}
}
}
return ans
}
1.3 测试结果
1.4 复杂度
- 时间复杂度:O(n2)
- 空间复杂度:O(n)。我们忽略存储答案的空间,额外的排序的空间复杂度为 O(logN)。然而我们修改了输入的数组nums,在实际情况下不一定允许,因此也可以看成使用了一个额外的数组存储了 nums 的副本并进行排序,空间复杂度为 O(N)。