【左右端点指针】LeetCode - 15. 三数之和

本文介绍如何使用双指针技巧在有序数组中寻找满足nums[k]+nums[i]+nums[j]=0的三个数的组合,通过固定指针和动态指针的移动实现去重,并提供了一个C++解决方案。涉及LeetCode 16题的解法分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

题目链接
在这里插入图片描述

解法

首先我发现左右端点指针的前提一般是有序序列,所以一般跟排序一块,这类题是这样,二分查找也是这样

思路: 一个固定指针 k 遍历数组,两个动指针 i,j 分设在数组索引 (k,len(nums)) 两端,通过双指针交替向中间移动,记录对于每个固定指针 k 的所有满足题目要求 nums[k] + nums[i] + nums[j] == 0 的 i,j 组合

  • 当 k > 0且nums[k] == nums[k - 1]时即跳过此元素。因为已经将 nums[k - 1] 的所有组合加入到结果中,本次双指针搜索只会得到重复组合。
  • i,j 分设在数组索引 (k,len(nums)) 两端,当 i < j 时循环计算s = nums[k] + nums[i] + nums[j],并按照以下规则执行双指针移动:
    1. 当s < 0时,i ++ 并跳过所有重复的nums[i];
    2. 当s > 0时,j - - 并跳过所有重复的nums[j];
    3. 当s == 0时,记录组合[k, i, j] 至 ans,执行 i ++ 和 j - - 并跳过所有重复的nums[i]和nums[j],防止记录到重复组合。
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int> > ans;
        sort(nums.begin(),nums.end());
        int len = nums.size();
        //限制条件:num[i]作为三者中最小值,一定不能超过0
        for(int i=0;i<len&&nums[i]<=0;i++)
        {
            //保证和上一次枚举的元素不一样
            if(i>0&&nums[i]==nums[i-1])
             continue;
            int start=i+1,end=len-1;
            while(start<end)
            {
                int sum=nums[start]+nums[end]+nums[i];
                if(sum==0)
                {
                    ans.push_back({nums[start],nums[end],nums[i]});
                    while(start<end&&nums[start]==nums[++start]);//去重
                    while(start<end&&nums[end]==nums[--end]);//去重
                }                 
                else if(sum>0)
                 while(start<end&&nums[end]==nums[--end]);//去重
                else
                 while(start<end&&nums[start]==nums[++start]);//去重          
            }            
        }      
        return ans;
    }
};

类似的练习题: 【左右端点指针】LeetCode - 16. 最接近的三数之和

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值