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 最接近的和是 00 + 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)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值