1_相向双指针_leetcode_16_4
16. 最接近的三数之和
给你一个长度为 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
解释:与 target 最接近的和是 0(0 + 0 + 0 = 0)。
提示:
3 <= nums.length <= 1000
-1000 <= nums[i] <= 1000
-104 <= target <= 104
方法 相向双指针
- 确保数组有序
- 判断指针移动条件,当前和cur_sum大于target 右指针左移,当前和cur_sum小于target ,左指针右移
- 返回值保存条件,当差值 diff < |cur_sum - target| 时需要记录
// C
int cmp(const void *a , const void*b){
return *(int *)a - *(int *)b;
}
int threeSumClosest(int* nums, int numsSize, int target) {
qsort(nums,numsSize,sizeof(int),cmp);
int diff = 30000;
int t_sum = 0;
for(int i = 0;i<numsSize-2;i++){
if(i!=0 && nums[i]==nums[i -1]) continue;
int sum = nums[i] + nums[i+1] +nums[i+2];
if(sum > target) if(sum -target< diff) return sum;
sum = nums[i] + nums[numsSize - 1] + nums[numsSize -2];
if(sum < target){
if(target - sum < diff ){
diff = target - sum;
t_sum= sum;
}
continue;
}
int l = i +1;
int r = numsSize - 1;
while(l < r){
sum = nums[i] + nums[l] + nums[r];
if(sum == target) return target;
else if(sum > target){
if(sum - target < diff){
diff = sum - target;
t_sum = sum;
}
r--;
}
else {
if(target - sum < diff){
diff = target - sum;
t_sum = sum;
}
l++;
}
}
}
return t_sum;
}
// C++
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
int n = nums.size();
int l,r,diff=300001;
int sum,ret;
sort(nums.begin(),nums.end());
for(int i = 0; i < n - 2; i++){
if(i > 0 && nums[i]==nums[i - 1]) continue;
sum = nums[i]+nums[i+1]+nums[i+2];
if(sum > target ){
if(diff > sum - target)
{
diff = sum - target;
return sum;
}
return ret;
}
sum = nums[i]+nums[n-1]+nums[n-2];
if(sum < target){
if(diff > target - sum){
diff = target - sum;
ret = sum;
}
continue;
}
l = i + 1;
r = n - 1;
while(l < r){
sum = nums[i] + nums[l] + nums[r];
if(sum > target){
if(diff > sum - target){
diff = sum - target;
ret = sum;
}
r--;
}
else if (sum < target){
if(diff > target - sum){
diff = target - sum;
ret = sum;
}
l++;
}
else return target;
}
}
return ret;
}
};
# python
class Solution:
def threeSumClosest(self, nums: List[int], target: int) -> int:
diff = 30000
r_sum = 0
nums.sort()
for i in range(len(nums)-2):
if i!=0 and nums[i] == nums[i - 1]: continue
cur_sum = nums[i] + nums[i + 1] + nums[i + 2]
if cur_sum >= target :
if diff > cur_sum - target: return cur_sum
cur_sum = nums[i] + nums[len(nums) - 1] + nums[len(nums)-2]
if cur_sum < target:
if target - cur_sum <diff:
diff = target - cur_sum
r_sum = cur_sum
continue
l = i + 1
r = len(nums) -1
while l < r:
cur_sum = nums[i] + nums[l] + nums[r]
if target > cur_sum:
if diff > target - cur_sum:
diff = target - cur_sum
r_sum = cur_sum
l+=1
elif cur_sum == target: return target
else :
if diff > cur_sum - target:
diff = cur_sum - target
r_sum = cur_sum
r-=1
return r_sum
- 时间复杂度: O ( n 2 ) O(n^2) O(n2)
- 空间复杂度: O ( l o g n ) O(logn) O(logn)