双指针解决返回所有和为 0 且不重复的三元组(力扣15-三数之和)

 题目(原题链接​​​​​​​)

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

题目分析:

1,对于三个数,可以尝试与两个数近似的的解题思路(两数之和),首先先sort将数据有序化,先利用循环来框定一个数,再对剩下的俩数利用头尾指针相向遍历,然后记录符合的数据,重复的就跳过;

代码分析:

1,对于第一位变量i遍历的时候,可以考虑此变量若与前一此遍历所对应的数据相同,可以将此变量++,既跳过此次循环,因为题目说不包含重复的三元组;

2,对于后两个相向变量,可以将执行过程的条件设定为(头j<尾k)以便及时终止不必要的过程,产生错误答案;

3,若i与后两个连续的数据相加,结果都>0的话,便可以结束所有的循环了,因为数据是依次增大的,当i递增到此处,无论后面的j和k怎么变化,结果都是会>0的,既无法满足=0的条件;

4,若i与数组最末尾的两个数据相加都<0,便可以结束此次i的循环了,直接i++;因为i与数组里的最大的两个值都小于0,说明这个i变量无法成立答案,于是便跳过;

5,利用for (++j; j < k && nums[j] == nums[j - 1]; ++j);来判断并修改j和k两个相向指针,可以快速的达到跳过重复元素的效果;

最后献上灵神的代码,详细可点入链接查看;

class Solution {
public:
    vector<vector<int>> threeSum(vector<int> &nums) {
        sort(nums.begin(), nums.end());
        vector<vector<int>> ans;
        int n = nums.size();
        for (int i = 0; i < n - 2; ++i) {
            int x = nums[i];
            if (i && x == nums[i - 1]) continue; // 跳过重复数字
            if (x + nums[i + 1] + nums[i + 2] > 0) break; // 优化一
            if (x + nums[n - 2] + nums[n - 1] < 0) continue; // 优化二
            int j = i + 1, k = n - 1;
            while (j < k) {
                int s = x + nums[j] + nums[k];
                if (s > 0) --k;
                else if (s < 0) ++j;
                else {
                    ans.push_back({x, nums[j], nums[k]});
                    for (++j; j < k && nums[j] == nums[j - 1]; ++j); // 跳过重复数字
                    for (--k; k > j && nums[k] == nums[k + 1]; --k); // 跳过重复数字
                }
            }
        }
        return ans;
    }
};

作者:灵茶山艾府
链接:https://leetcode.cn/problems/3sum/solutions/1968332/shuang-zhi-zhen-xiang-bu-ming-bai-yi-ge-pno55/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值