技术交流可以加:
本人微信:xcg852390212
本人qq:852390212
学习交流qq群1(已满): 962535112
学习交流qq群2: 780902027
最接近的三数之和
给定一个包括 n 个整数的数组 nums
和 一个目标值 target
。找出 nums
中的三个整数,使得它们的和与 target
最接近。返回这三个数的和。假定每组输入只存在唯一答案。
例如,给定数组 nums = [-1,2,1,-4], 和 target = 1.
与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).
解答
思路和三数之和类似:先排序数组,遍历数组取第一个数(只到数组倒数第三个元素
),剩下两个数在第一个数的右边部分,定义双指针l和r分别指向i+1
和len-1
,当前三数和tmp = nums[l] + nums[r] + nums[i]
,然后向中间移动,移动规则如下:
- 如果
tmp < target
,则++l,同时比较abs(tmp - target)
和abs(res - target)
,取较小值对应的那个三数和给结果res
- 如果
tmp > target
,则–r,同时比较abs(tmp - target)
和abs(res - target)
,取较小值对应的那个三数和给结果res
- 如果
tmp == target
,则tmp即为所求
- 时间复杂度:O(n2)
- 空间复杂度:O(1)
C++代码
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
sort(nums.begin(),nums.end());
int len = nums.size();
if(len < 3) return INT_MAX;
int res = nums[0] + nums[1] + nums[2];
for(int i=0;i<len-2;i++)
{
if(i == 0 || nums[i] != nums[i-1])
{
int l = i+1,r = len-1;
while(l < r)
{
int tmp = nums[l] + nums[r] + nums[i];
if(tmp < target)
{
res = abs(res - target) < abs(target - tmp) ? res : tmp;
++l;
}
else if(tmp > target)
{
res = abs(res - target) < abs(target - tmp) ? res : tmp;
--r;
}
else{
return tmp;
}
if(i > 0)
{
while(l < r && nums[l] == nums[l-1]) ++l;
while(l < r && nums[r] == nums[r+1]) --r;
}
}
}
}
return res;
}
};
Python代码
class Solution:
def threeSumClosest(self, nums: List[int], target: int) -> int:
n = len(nums)
if n < 3:
return []
nums.sort()
res = nums[0] + nums[1] + nums[2]
for i in range(n - 2):
if i == 0 or (i > 0 and nums[i] != nums[i - 1]):
l = i + 1
r = n - 1
while l < r:
tmp = nums[i] + nums[l] + nums[r]
if abs(tmp - target) < abs(res - target):
res = tmp
if tmp < target:
l += 1
elif tmp > target:
r -= 1
else:
return tmp
while l < r and nums[l] == nums[l - 1]:
l += 1
while l < r and nums[r - 1] == nums[r]:
r -= 1
if r < n - 1 and nums[r] == nums[r + 1]:
r -= 1
return res