LeetCode 15. 3Sum; 16. 3Sum Closest; 259. 3Sum Smaller; 18. 4Sum

15. 3Sum

Two Sum 的 follow up

Two Sum 使用hashtable做到O(n)时间复杂度

所以看到这道题,第一想法是固定一个元素,剩下的用 Two Sum 处理。但是由于这道题有重复元素存在,最后去重会TLE,因此不能这样做。

在一个有序数组里寻找加和为给定值的两个元素,我们可以使用 Two Pointers 从两侧向中间来寻找。

对于这道题,我们可以先对数组进行排序,固定一个数nums[i],用 Two Pointers 寻找加和等于 -nums[i] 的两个数。每次两个pointer都跳过重复的元素,固定的nums[i]也跳过重复的元素,这样最后答案里所有的解都是唯一的了。

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> res;
        sort(nums.begin(),nums.end());
        for (int i=0;i<nums.size();++i){
            int target= -nums[i];
            int low=i+1, high=nums.size()-1;
            while (low<high){
                int sum=nums[low]+nums[high];
                if (sum<target) ++low;
                else if (sum>target) --high;
                else{ 
                    vector<int> tri({nums[i],nums[low],nums[high]});
                    res.push_back(tri);
                    
                    //skip the same value as nums[low]
                    while (low<high && nums[low]==tri[1]) ++low;
                    
                    //skip the same value as nums[high]
                    while (low<high && nums[high]==tri[2]) --high;
                }
            }
            //skip the same value as nums[i]
            while (i+1<nums.size() && nums[i+1]==nums[i])
                ++i;
        }
        return res;
    }
};

 

16. 3Sum Closest

和 3 Sum 几乎一模一样,复习一下。

class Solution {
public:
    int threeSumClosest(vector<int>& nums, int target) {
        if (nums.size()<3) return 0;
        int res=nums[0]+nums[1]+nums[2];
        sort(nums.begin(),nums.end());
        
        for (int i=0;i<nums.size();++i){
            if (i>=1 && nums[i]==nums[i-1]) continue;
            int low=i+1, high=nums.size()-1;
            
            while (low<high){
                int curSum=nums[i]+nums[low]+nums[high];
                if (curSum==target) return curSum;
                if (abs(curSum-target)<abs(res-target))
                    res = curSum;
                if (curSum<target) ++low;
                else if (curSum>target) --high;
            }
        }
        return res;
    }
};

 

259. 3Sum Smaller

curSum<target 时,low不变,high从high到low+1都是可行的,所以+=high-low。

class Solution {
public:
    int threeSumSmaller(vector<int>& nums, int target) {
        int cnt=0;
        sort(nums.begin(),nums.end());
        
        for (int i=0;i<nums.size();++i){
            int low=i+1, high=nums.size()-1;
            while (low<high){
                int curSum=nums[i]+nums[low]+nums[high];
                if (curSum<target){
                    cnt += high-low; // the third num can be any element in (low,high]
                    ++low;
                }else --high;
            }
        }
        return cnt;
    }
};

 

18. 4Sum

还是一样的套路,把之前的写法跟精简了一下:

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        vector<vector<int>> res;
        sort(nums.begin(),nums.end());
        for (int i=0;i<nums.size();++i){
            if (i>0 && nums[i]==nums[i-1]) continue;
            for (int j=i+1;j<nums.size();++j){
                if (j>i+1 && nums[j]==nums[j-1]) continue;
                int low=j+1, high=nums.size()-1;
                while (low<high){
                    int sum=nums[i]+nums[j]+nums[low]+nums[high];
                    if (sum==target){
                        res.push_back({nums[i],nums[j],nums[low],nums[high]});
                        ++low; --high;
                        while (low<high && nums[low]==nums[low-1]) ++low;
                        while (low<high && nums[high]==nums[high+1]) --high;
                    }else if (sum<target) ++low;
                    else --high;
                }
            }
        }
        return res;
    }
};

 

转载于:https://www.cnblogs.com/hankunyan/p/9552049.html

项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还[基于Python]自己写的一个微信跳一跳自动游戏程序(针对安卓手机)。 全自动运行 自动适应不同分辨率 自动调整各个参数误差.zip行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值