Leetcode15.三数之和(c++,双指针解法,附详细解释~)

在第一次尝试的时候用了哈希表,结果在去重时依次与现有的解进行比较,若已有相同的则放弃,否则加入解集。

结果显示超时!

于是使用了双指针法。整体思路:

(1)先用sort函数将数组由大到小排序 ,再从nums.begin数值依次递增,选定一个数。选定数后的第一个数则为双指针中的左指针,最后一个数值为右指针。

(2)如果选定的数+左指针+右指针数值为0,则将其作为一种解的情况,移动指针;

          如果选定的数+左指针+右指针数值小于0,则表示数值还需增大,则向右移动左指针(增大左指针数值);

          如果选定的数+左指针+右指针数值大于0,则表示数值还需减小,则向左移动右指针(减小右指针数值);

(3)本次选定的数左右指针相遇后,则继续向右移动选定的数。

移动指针时,为了防止出现解相同的情况,如果指针移动后所指数值与移动之前数值相同,则继续向下移动。选定数时的移动依旧同理。

(代码如下~)

class Solution {
public:
    vector< vector<int> > threeSum(vector<int>& nums) {
        vector< vector<int> > res;
        if(nums.size()<=2) return res;
        sort(nums.begin(), nums.end());//先将数组排序,为了更好的用双指针法
        for(int i=0;i<nums.size()-2;){
            //先选定一个数
            for(int start=i+1,end=nums.size()-1;start<end;){
                //当前两个指针数值+选定数为0
                if(nums[i]+nums[start]+nums[end]==0){
                    vector<int> num(3);
                    num[0]=nums[i];num[1]=nums[start];num[2]=nums[end];
                    res.push_back(num);
                    start++;end--;
                    //如果指针前后所指数值相同,为了去重则继续后移
                    while(nums[start-1]==nums[start]) {
                        start++;
                        if(start>=nums.size()) break;
                    }
                    while(nums[end+1]==nums[end]) {
                        end--;
                        if(end<0) break;
                    }
                }
                else {
                    //当前两个指针数值+选定数小于0,将start改为更大的即+1
                    if(nums[i]+nums[start]+nums[end]<0){
                        start++;
                        //如果start+1后数值相同,则继续后移
                        while(nums[start-1]==nums[start]) {
                            start++;
                            if(start>=nums.size()) break;
                        }
                    }
                    //当前两个指针数值+选定数大于0,将end改为更大的即-1
                    else if(nums[i]+nums[start]+nums[end]>0){
                        end--;
                        //如果end-1后数值相同,则继续前移
                        while(nums[end+1]==nums[end]) {
                            end--;
                            if(end<0) break;
                        }
                    }
                }
            }
            i++;
            //为去重,如果选定数与之前相同,则继续后移
            while(nums[i-1]==nums[i]) {
                i++;
                if(i>=nums.size()) break;
            }
        }
        return res;
    }
    
};

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值