[ LeetCode ] #16. 3Sum Closest(三数之和 C++ & Python)

题目:16. 3Sum Closest

difficulty: Medium

Given an array nums of n integers and an integer target, find three integers in nums such that the sum is closest to target. Return the sum of the three integers. You may assume that each input would have exactly one solution.

Example:

Given array nums = [-1, 2, 1, -4], and target = 1.

The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).

题意:

给一个数列,和一个整数target,在数列中求出三个数之和sum,并使得sum与target之差最小。数列保证只有一个最优解。

分析:

本题与上一题相似度非常高,可以使用相同的解题思路:

  1. 输入数列为乱序,首先进行排序。
  2. 一次循环遍历每个数,计算当前数和当前数的下一个及最后一个的和,判断当前和是否为最小,如果是则替换记录最小值。
  3. 按照上述所求的的和判断 后续搜索位置,另外还有一个特例 当最小值为0时,可以终止循环,因为题目保证仅有唯一最优解。
  4. 过滤掉相邻且相等的元素,可以避免不必要的计算。
  5. 实现如下。

Code & C++

class Solution {
public:
    int threeSumClosest(vector<int>& nums, int target) {
        sort(nums.begin(), nums.end());
        int slen = nums.size();
        if(slen == 3)return nums[0]+nums[1]+nums[2];
        int smin=1<<20,ans=0;
        for(int i=0;i<slen;++i){
            int first = nums[i], front=i+1, back=slen-1;
            int tmp = target-first;
            while( front< back){
                int sum3 = nums[front] + nums[back];
                if(sum3<tmp){
                    ++front;
                }else if(sum3>tmp){
                    --back;
                }else{
                    return target;
                }
                if(smin>abs(tmp-sum3)){
                    ans = sum3 + nums[i];
                    smin = abs(tmp-sum3);
                }
            }
            while(i<slen-1 && nums[i]==nums[i+1])++i;
        }
        return ans;
    }
};

结果:

Runtime: 8 ms, faster than 100.00% of C++ online submissions for 3Sum Closest.

Memory Usage: 9.4 MB, less than 73.26% of C++ online submissions for 3Sum Closest.

Code & Python

class Solution:
    def threeSumClosest(self, nums: List[int], target: int) -> int:
        slen = len(nums)
        if slen==0:return
        nums.sort()
        i, smin, ans=0, 1<<30, 0
        while i<slen:
            first ,front ,back = nums[i], i+1, slen-1
            while front<back:
                sum = first + nums[front] + nums[back]
                if smin > abs(target-sum):
                    smin = abs(target-sum)
                    ans = sum
                    if smin == 0:break
                if sum < target:
                    if front<back and nums[front]==nums[front+1]:
                        while front<back and nums[front]==nums[front+1]:front+=1
                    else:
                        front+=1
                else:
                    if back>front and nums[back]==nums[back-1]:
                        while front<back and nums[back]==nums[back-1]: back-=1
                    else:
                        back-=1
            if smin==0:
                break
            i+=1
            while i<slen and nums[i]==nums[i-1]:i+=1
        return ans

结果:

Runtime: 100 ms, faster than 84.33% of Python3 online submissions for 3Sum Closest.

Memory Usage: 13.1 MB, less than 5.29% of Python3 online submissions for 3Sum Closest.

 

Status:Accepted

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值