【C++算法】8.双指针_三数之和

文章目录


题目链接:

15.三数之和


题目描述:


解法

解法一:排序+暴力枚举+利用set去重O(n3)

例如nums=[-1,0,1,2,-1,-4]

[-1,0,1][0,1,-1][1,0,-1]下标不同但是都满足 ,这个题难在去重

可以通过排序去重,先把数组排序再找,就不会出现上面一行出现的问题了。

但是这里举例的nums里面由两个-1,可能会出现[-1,0,1]两次。这个就可以通过set容器去除。
解法二:排序+双指针

  1. 先排序
  2. 固定一个数a
  3. 在该数后面的区间内,利用双指针算法快速找到两个数的和等于-a

处理细节:

  1. 去重

    找到一种结果之后,leftright指针要跳过重复元素

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

  2. 不漏掉

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


C++ 算法代码:

cpp 复制代码
class Solution 
{
    public:
    vector<vector<int>> threeSum(vector<int>& nums) 
    {
        vector<vector<int>> ret;//用ret记录结果
        // 1. 排序
        sort(nums.begin(), nums.end());
        // 2. 利用双指针解决问题
        int n = nums.size();
        for(int i = 0; i < n; ) // 固定数 a
        {
            if(nums[i] > 0){
                break; // 小优化
            }
            int left = i + 1, right = n - 1, target = -nums[i];
            while(left < right)
            {
                int sum = nums[left] + nums[right];
                if(sum > target){
                    right--;
                }
                else if(sum < target){
                    left++;
                }
                else{//说明找到最终结果
                    ret.push_back({nums[i], nums[left], nums[right]});//把三个数放到ret里面,{}会形成一个vector int的数组放到ret里面
                    left++, 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 ret;
    }
};

图解

nums=[-4,-4,-1,0,0,0,1,1,4,4,5,6]

  1. n=12,进入for循环,i=0,left=1,right=11,target=4,left < right进入while循环,sum=2<target,left++
  1. sum=-1+6=5>target,right--
  1. sum=-1+5=4=targe,把[-4,-1,5]放到ret里面,left++, right--
  1. sum=0+4=4=targe,把[-4,0,4]放到ret里面,left++, right--,执行去重操作
  1. sum=1+1=2<targe,left++,跳出while循环,i++,执行去重,然后开始第二轮双指针算法。
  1. 后面的步骤类似,就不多赘述了。
相关推荐
帅次8 分钟前
Kotlin 与 Java 互操作:混合工程里的平台类型与 API 边界
java·开发语言·kotlin·suspend·nullable
六点_dn9 分钟前
Linux学习笔记-printf命令
linux·运维·算法
遥感知识服务1 小时前
Sentinel-1 + DEM + FwDET + 随机森林:从快速水深初估到多因子误差修正
算法·随机森林·sentinel
来一碗刘肉面1 小时前
顺序表与链表的比较
数据结构·算法·链表
alphaTao1 小时前
LeetCode 每日一题 2026/7/13-2026/7/19
算法·leetcode
nnerddboy2 小时前
脑电信号处理实战 03 | 运动想象脑机接口入门:ERD/ERS、CSP 空间滤波与左右拳想象解码
算法·信号处理
dtq04242 小时前
C语言-结构体详解
c语言·开发语言·学习
梅雅达编程笔记2 小时前
编程启蒙|Scratch 转 Python 系列第9天:字典/哈希表积木双向对照(AI大模型参数配置表实战)
开发语言·人工智能·python·numpy·pandas
持力行2 小时前
C++与Java变量声明、定义及内存分配的核心区别
java·开发语言·c++
QN1幻化引擎3 小时前
Dalin L — 我造了一门支持中文编程的语言,完整移植到 Rust 了
人工智能·算法·机器学习