力扣 15.三数之和(medium)(双指针)

15. 三数之和 - 力扣(LeetCode)

解法一:排序后暴力枚举然后利用set去重

答案中不可以包含重复的三元组,输出的顺序和三元组的顺序并不重要。根据这两点要求我们需要对数组进行排序,排序后三层for循环嵌套遍历数组可以找出所有满足(i != j、i != k 且 j != k ,同时还满足 numsi + numsj + numsk == 0)的三元组,而在这些三元组中,重复的三元组因为数组有序而完全一样(包括顺序)然后把全部的三元组一股脑扔给set容器,set会帮我们完成去重,最后输出结果。时间复杂度O(n^3) (该解法只解释思路,不做具体演示,我们主要学习下面这种解法)

解法二:排序+双指针

算法思路:

1.先对数组排序,令其变为有序,固定左侧i,定义t=-numi,定义left,right指针,l,r分别是其所指向的值,在left,right区间中遍历使l+r=t

2.若l+r>t,right--,若l+r<t,left++,若l+r=t,存储三元组target,left++,ight--。l,r循环直至left>=right

3.然后i++,开始下一轮循环直至i=n(一个小优化:当numi>0时就可以结束循环了,之后不可能有符合条件的三元组)

处理细节问题:

1.去重

当找到符合条件的三元组时,left,right要跳过重复元素s

当使用完一次双指针算法后,i也要跳过重复元素

2.不漏

找到一种结果后不要停,缩小区间继续寻找

3.避免越界(特殊情况)

每次跳过重复元素时都要判断是否越界

代码:

cpp 复制代码
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        int n=nums.size();
        vector<vector<int>> a;
        for(int i=0;i<n;)
        {
            if(nums[i] > 0) break; // 小优化
            int left=i+1,right=n-1,t=-nums[i];
            while(left<right)
            {
                if(nums[left]+nums[right]>t)
                right--;
                else if(nums[left]+nums[right]<t)
                left++;
                else
                {
                    //找到一种结果后不要停,缩小区间继续寻找
                    a.push_back({nums[i],nums[left++],nums[right--]});
                    //left,right去重,每次跳过重复元素时都要判断是否越界
                    while(left<right&&nums[left]==nums[left-1])left++;
                    while(left<right&&nums[right]==nums[right+1])right--;
                }
            }
            i++;
            //i去重
            while(i < n && nums[i] == nums[i - 1]) i++;
        }
        return a;
    }
};
相关推荐
想吃火锅10054 小时前
【leetcode】14.最长公共前缀js
算法·leetcode·职场和发展
云絮.5 小时前
数据库操作
数据库·mysql·算法·oracle
小林ixn5 小时前
LeetCode 206. 反转链表(迭代 + 递归详解)
算法·leetcode·链表
凡人叶枫6 小时前
Effective C++ 条款17:以独立语句将 newed 对象置入智能指针
java·linux·开发语言·c++·算法
我爱cope7 小时前
【Agent智能体26 | 多智能体-多智能体工作流】
人工智能·设计模式·语言模型·职场和发展
菜鸟‍7 小时前
LeetCode 1 27 和 704 || 两数之和 移除元素 二分查找
算法·leetcode·职场和发展
退休倒计时8 小时前
【每日一题】LeetCode 142. 环形链表 II TypeScript
算法·leetcode·链表·typescript
popcorn_min9 小时前
Digits 手写数字识别:随机森林多分类 + 像素级特征热力图
算法·随机森林·分类
liulilittle9 小时前
拥塞控制:排水终止的两种决策:OR 与 AND
网络·tcp/ip·计算机网络·算法·信息与通信·tcp·通信
weixin_3077791310 小时前
从脚本执行到智能体协作:AI辅助测试能力的范式重构
运维·开发语言·人工智能·算法·测试用例