题解 | #三数之和#

三数之和

https://www.nowcoder.com/practice/345e2ed5f81d4017bbb8cc6055b0b711

//参考了代码随想录15.三数之和的写法
//本题的思路是“三指针”,先对数组进行排序,排序后用遍历数组,指针i指向的就是数字a,指针i的下一个位置记为left,即数字b,然后再拿一个指针指向数组中的最后一个数字,即数字c。
//通过不断判断a+b+c与0的关系,比0大就让right左移,比0小就让left右移。通过这种方式不断收缩left与right,直到找到a+b+c=0为止,将其添加进列表里。当然,一个i中可能有多解,在这种情况下依然需要继续收缩left与right。也有可能没解,这样收缩到left==right时,就步进i。
//这题的一大难点在于“去重”。对a的去重时应该使用num[i]==num[i-1],而不能使用num[i]==num[i+1],避免某一对三元组还没被遍历过就先被排除掉了。比如[x,x,x,-1,-1,y,y,2]这种情况下,原本-1,-1,2可以构成一个三元组,但i刚指向第一个-1时就把该情况排除了,是不行的。
//对b和c的去重见代码中
#include <vector>
class Solution {
  public:

    vector<vector<int> > threeSum(vector<int>& num) {
        vector<vector<int> >result;
        if (num.size() < 3 ) //非法情况。
            return result;
        sort(num.begin(), num.end()); //对num进行排序。

        for (int i = 0; i < num.size(); i++) {
            if (num[i] >
                    0) //a大于0了,b和c在排序数组中也必然大于0,和不可能等于0
                break;
            if (i > 0 && num[i] == num[i - 1]) //对a去重。
                continue;
            int left = i + 1;
            int right = num.size() - 1;

            while (right > left) {
                // 去重复逻辑如果放在这里,0,0,0 的情况,可能直接导致 right<=left 了,从而漏掉了 0,0,0 这种三元组。很遗憾我一开始也是这么写的。
                /*
                while (right > left && nums[right] == nums[right - 1]) right--;
                while (right > left && nums[left] == nums[left + 1]) left++;
                */
                if (num[i] + num[left] + num[right] > 0) {
                    right--;
                } else if (num[i] + num[left] + num[right] < 0) {
                    left++;
                } else  {
                    result.push_back({num[i], num[left], num[right]});
                    while (right > left && num[right] == num[right - 1])right--;
                    while (right > left && num[left] == num[left + 1])left++;
                    right--;//如果只平移right,不平移left,却也能依然符合0的话,说明right在平移前后都是相同的值,是重复的了,所以还是都得平移。
                    left++;
                }

            }
        }
        return result;
    }
};

全部评论

相关推荐

服从性笔试吗,发这么多笔,现在还在发。
蟑螂恶霸zZ:傻 x 公司,发两次笔试,两次部门匹配挂,
投递金山WPS等公司10个岗位 >
点赞 评论 收藏
分享
我见java多妩媚:大外包
点赞 评论 收藏
分享
10-25 12:05
已编辑
湖南科技大学 Java
若梦难了:我有你这简历,已经大厂乱杀了
点赞 评论 收藏
分享
1 收藏 评论
分享
牛客网
牛客企业服务