每日算法系列【LeetCode 16】最接近的三数之和
题目描述
给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。
示例1
输入:
nums = [-1,2,1,-4], target = 1.
输出:
2
解释:
与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).
题解
最暴力的方法就是直接枚举三个不同的数,然后求出差值最小的和,但是这样时间复杂度是 ,太高了。
那么我们先枚举一个数试试,并且假设它是最小的数,然后寻找比它大的两个数就行了,这就需要我们先对数组进行排序(假设排序后数组是 )。
如果枚举的数是 ,那么我们只需要寻找和 差值最小的两个数之和就行了。
如果用双指针的方法,初始时令 ,同时 。那么如果 ,就说明 太大了,需要左移。否则的话如果 ,就说明 太小了,需要右移。在不断移动的过程中更新最小差值就行了,因为 和 最终一共只移动了 步,所以总的时间复杂度只有 ,忽略低阶项之后只有 ,还是可以接受的。
代码
c++
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
int n = nums.size(), res = 10000000;
sort(nums.begin(), nums.end());
for (int i = 0; i < n - 2; ++i) {
int l = i + 1, r = n - 1;
while (l < r) {
int sum = nums[i] + nums[l] + nums[r];
if (sum == target) return sum;
if (abs(sum-target) < abs(res-target)) res = sum;
if (sum > target) r--;
else l++;
}
}
return res;
}
};
python
class Solution:
def threeSumClosest(self, nums: List[int], target: int) -> int:
n, res = len(nums), 10000000
nums.sort()
for i in range(n-2):
l, r = i+1, n-1
while l < r:
s = nums[i] + nums[l] + nums[r]
if s == target:
return s
if abs(s-target) < abs(res-target):
res = s
if s > target:
r -= 1
else:
l += 1
return res
算法码上来 文章被收录于专栏
公众号「算法码上来」。godweiyang带你学习算法,不管是编程算法,还是深度学习、自然语言处理算法都一网打尽,更有各种计算机新鲜知识和你分享。别急,算法码上来。