双指针:三数之和

力扣:l15. 三数之和 - 力扣(LeetCode)

 参考的视频力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

 还是贴一下代码:

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        int n=nums.size();vector<vector<int>> ans;
        for(int i=0;i<n-2;i
        ++)
        {
            int x=nums[i];
            if(x+nums[i+1]+nums[i+2]>0)
            break;
            if(x+nums[n-1]+nums[n-2]<0)
            continue;
            if(i>0&&nums[i-1]==x)
            continue;
            int j=i+1,k=n-1;
            while(j<k)
            {
                if(x+nums[j]+nums[k]>0)
                k--;
                else if(x+nums[j]+nums[k]<0)
                j++;
                else
                {
                    ans.push_back(vector<int>{x,nums[j],nums[k]});
                    j++;
                    while(j<k&&nums[j]==nums[j
                    -1]) j+=1;
                   k--; while(j<k&&nums[k]==nums[k+1])
                    k-=1;
                    
                }
            }
        }
        return ans;
    }
};

1.太久没用vector的东西,排序方法都不知道怎么调用了。

末尾添加元素用push_back()。

发现vector内部没有直接调用的方法,而是有一个模板函数sort(并且要包含头文件#include <algorithm>):C++中使用sort对常见容器排序_c++ vector sort-CSDN博客

 2.三数之和是枚举第一个数,剩下两个数按双指针处理两数之和的方法来处理,所以需要对数组进行一次排序。

3.题目强调了“注意:答案中不可以包含重复的三元组。”,所以需要有去除重复的操作,因为经过了排序,所以在枚举第一个数和处理两数之和移动双指针时,只要出现和前面一个数相同的元素就跳过,因为三元组不重复,所以这个重复的数的组合肯定已经全部找到,剩下的两数之和找到的二个数,如果一个数还是相同的,另一个数肯定也就确定最多只能找到相同的。

4.在移动指针时,要注意判断下标越界,并且要把判断条件写在&&的前面,因为&&前面的条件先判断,如果不成立后面的条件判断不会执行。

if (i > 0&& x == nums[i - 1] ) continue;

这一句要把i>0放在&&前面,避免出现下标为负的情况。

同理,双指针移动还要注意两个指针的大小(左右)关系的成立,比如

while(j<k&&nums[j]==nums[j-1]) j+=1;

 不只是外部的while(j<k)要执行这个判断,在求两数之和去除重复的组合时移动指针时也要有这个判断,并且j<k也要放在&&的前面。

如果写在后面会出现这个错误提示:

Line 1037: Char 34: runtime error: addition of unsigned offset to 0x502000000290 overflowed to 0x50200000028c (stl_vector.h)

5.两个优化:

if(x+nums[i+1]+nums[i+2]>0) break;
if(x+nums[n-1]+nums[n-2]<0) continue;

第一个优化是如果目前最小的三个数加起来都大于0,那么剩下的组合肯定都大于0(排除了重复就只有大于0),另外这个已经包括了if(nums[i] > 0) break;的判断。

第二个优化是枚举的第一个数和剩下的两个最大的数加起来都小于0,那么不可能出现包括这个第一个数的三元组合等于0,所以跳过这轮枚举。注意是跳过这轮,continue,因为下一个数的枚举再组合是有可能大于等于0的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

guts350

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值