力扣 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;
    }
};
相关推荐
阳明山水16 分钟前
校准分位数驱动智能库存决策
人工智能·深度学习·算法·机器学习·架构
别动我齐刘海1 小时前
ROS2 Jazzy + C++ 实战路线——进阶学习3
c++·人工智能·vscode·python·算法·机器学习·机器人
zhangfeng11332 小时前
《从“人工适配“到“智能生成“:KernelSwift 跨国产芯片算子迁移全栈方案解读》 —— 强调范式跃迁和跨硬件属性,适合偏架构分析的写法
人工智能·算法·华为·ai编程·npu
0+1112 小时前
算法 --滑动窗口
c++·算法·leetcode
天真小巫2 小时前
2026.9.19总结
职场和发展
reikocao2 小时前
大场景下 Hessian 特征值放大与退化检测
算法
hetao17338372 小时前
2026-09-18 hetao1733837 的刷题记录
c++·算法
wuyk5553 小时前
21.计数排序:不用比较的“空间换时间”排序算法
python·算法·排序算法
Rabitebla3 小时前
【Linux系统编程】 指令(二):一条路径是怎么定位到文件的
linux·c++·笔记·学习·算法
顶点多余3 小时前
9.20 知识点查漏补缺
linux·面试·职场和发展