当前位置: 首页 > news >正文

【LeetCode】15.三数之和

目录

题目

题目链接:LeetCode-15题

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。

题目要求

  1. 满足 i != j、i != k 且 j != k (下标不同)
  2. nums[i] + nums[j] + nums[k] == 0
  3. 不重复的三元组

算法解法

算法一: 排序 + 暴力枚举 + set去重 (O( n 3 n^{3} n3))

排序再枚举,可以将重复的三元组变成相同的三元组,再去重即可。
在这里插入图片描述

简单解法,不讲解。

算法二: 排序 + 双指针

一旦排序应该思考能否使用双指针或者二分。

  1. 排序
  2. 固定一个数a
  3. 在该数后面的区间内,利用双指针算法一直寻找两个数的和等于-a即可
  4. 双指针算法:因为排序了,所以如果两个数相加如果大于目标值,说明中间的数字已经不可能等于目标值了,只有减小最大值(right–),才有机会得到目标值。反之,如果两个数相加小于目标值,直接left++;
    在这里插入图片描述
  • 细节问题:
    • 去重
      • 因为排序,我们会获得相同的结果,所以我们固定的数字如果与前一个相同,需要跳过。(跳过重复元素)
      • 双指针算法之间,left和right指针也需要跳过重复元素,原因是因为两个数字相加已经得到了-a,那么这两个数字必须一起存在才能得到对应的-a。也就是要么重复这两个数字,要么不能得到-a。

代码

class Solution {
public:
    vector<vector<int>> ret;
    vector<vector<int>> threeSum(vector<int>& nums) {
        //排序
        sort(nums.begin(),nums.end());

        int n = nums.size();
        for(int i =0;i<n;) //固定数a
        {
            //利用双指针解决问题
            int left = i+1;
            int right = n-1;
            int 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]});
                    left++,right--;
                    //去重并且防止越界
                    while(nums[left] == nums[left-1] && left < right)left++;
                    while(nums[right] == nums[right+1] && right > left)right--;
                }
            }
            //去重固定元素
            i++;
            while(i<n && nums[i] == nums[i-1]) i++;
        }
        return ret;
    }
};

相关文章:

  • Java 实现简单动态字符串
  • 机器学习--逻辑回归模型
  • MyBatis映射文件常用元素详解与示例
  • 青少年编程与数学 02-009 Django 5 Web 编程 16课题、权限管理
  • 【2025最新计算机毕业设计】基于SpringBoot+Vue药管家家庭医药品回收系统【提供源码+答辩PPT+文档+项目部署】
  • 论文阅读_用于低频隔振的高负刚度新型阵列磁性弹簧的分析与设计_1
  • MySQL智障离谱问题,删了库确还存在、也不能再创建同名库
  • linux kasan 使用举例
  • Spring-AOP
  • Windows Docker运行Implicit-SVSDF-Planner
  • Python 面试常见问题解析
  • DockerDesktop更改默认的磁盘镜像地存储位置
  • 使用python进行数据分析工作,要掌握哪些数学知识?
  • Linux下学【MySQL】常用函数助你成为数据库大师~(配sql+实操图+案例巩固 通俗易懂版~)
  • Java8新特性Optional,Function,Supplier,Consumer
  • 计算机网络之网络层(网络层的功能,异构网络互联,路由与转发,SDN基本概念,拥塞控制)
  • 【办公类-90-01】】20250213中班周计划四类活动的写法(分散运动、户外游戏、个别化(美工室图书吧探索室))
  • Redis过期机制
  • 【ISO 14229-1:2023 UDS诊断全量测试用例清单系列:第九节】
  • 用deepseek学大模型03-数学基础 概率论 最大似然估计(MLE)最大后验估计(MAP)
  • 5月起,这些新规将施行
  • 投资者建议发行优惠套票给“被套”小股东,张家界:将研究考虑
  • 移动互联网未成年人模式正式发布
  • 4月制造业PMI为49%,比上月下降1.5个百分点
  • 发挥全国劳模示范引领作用,加速汽车产业电智化转型
  • 赛力斯拟赴港上市:去年扭亏为盈净利59亿元,三年内实现百万销量目标