[LeetCode]day21 15.三数之和

news2025/2/13 12:28:10

题目链接

题目描述

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

注意:答案中不可以包含重复的三元组。

示例 1:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。
示例 2:

输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0 。
示例 3:

输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0 。

解题

审题

注意这道题是需要去重的,可以观察示例1,有两种情况都是0+1+(-1),这两种情况就视为一种

解题

版本一:纯暴力解法

最容易想到的就是用三重循环.

  • 找到一个满足条件的数组
  • 对其进行排序(假如有两种结果 i,j,k对应的元素分别为1,2,-3,另一种结果对应的元素是-3,1,2,则两个数组{1,2,-3},{-3,1,2}排序后都是{-3,1,2},是相同的,方便后面进行去重)
  • 判断结果数组中是否有相同的数组,如果没有,加入结果数组中
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
    //存放所有可能的结果数组
     vector<vector<int>>result;
        for(int i=0;i<nums.size();i++){
            for(int j=0;j<nums.size();j++){
              for(int z=0;z<nums.size();z++){
                //三个元素下标各不相同且相加为0
                if((nums[i]+nums[j]+nums[z]==0) &&i!=j&&i!=z&&j!=z){
                    //将这三个元素按顺序组成数组
                    vector<int>ans={nums[i],nums[j],nums[z]};
                    //排序
                    sort(ans.begin(),ans.end());
                    int find=false;
                    //如果result里已经有相同的数组,则就不放入了
                   for(int a=0;a<result.size();a++){
                    if(result[a]==ans){
                        find=true;
                        break;
                    }
                   }
                   if(!find)
                    result.push_back(ans);
                }
              }
             }
        }
        return result;

    }
};

测试通过,提交喜提超时

版本二 双指针法

请添加图片描述

思路分析:
  • 排序数组:首先对数组进行排序,以便后续处理。

  • 遍历固定一个数:遍历数组中的每个元素作为三元组的第一个数。

  • 双指针寻找另外两个数:对于每个固定的数,使用左右指针在剩余数组中寻找另外两个数,使得三个数的和为0。(如果总和<0,left++,总和大于0,right–,总和为0,两个都向中间移动)

  • 去重处理:跳过重复的元素,避免生成重复的三元组。

易错点:去重操作
如上面的图,对于下标为i的去重方法和left,right的去重方法有所不同
第一个元素的去重: if(i>0&&nums[i]==nums[i-1])continue;
为什么不是判断nums[i]==nums[i+1]呢??
如-1,-1,-1,0,1,2
有可能是
(1)i=0,left=1,right=5 (2)i=1,left2,right=5
这两种情况其实是一样的,都是-1+(-1)+2
如果是判断nums[i]==nums[i+1] i就直接移到下标为2的位置上了,有效的三元组就被略过去了
如果是判断nums[i]==nums[i-1],就可以有效的略过相同的情况
对于第二个第三个元素的去重:
while(nums[right]==nums[right-1]&&left<right) right–;
while(nums[left]==nums[left+1]&&left<right)left++;

看起来都挺抽象的,其实自己画个图试着走一遍流程就能理解了

错误版本
class Solution {
public:
   vector<vector<int>> threeSum(vector<int>& nums) {
   vector<vector<int>>result;
   int left=0,right=0;
   //先对数组进行排序
  sort(nums.begin(),nums.end());
  for(int i=0;i<nums.size();i++){
   if(nums[i]>0)return result; //如果第一个元素大于0,三个元素之和不可能大于0
   if(i>0&&nums[i]==nums[i-1])continue;
   left=i+1;
   right=nums.size()-1;
   while(right>left){
       if(nums[i]+nums[right]+nums[left]>0){
           right--;  
           while(nums[right]==nums[right-1]&&left<right) right--;
       }else if(nums[i]+nums[right]+nums[left]<0){
           left++;
           while(nums[left]==nums[left+1]&&left<right)left++;
       }else{
          result.push_back(vector<int>{nums[i],nums[left],nums[right]});
           //while(nums[right]==nums[right-1]&&left<right) right--;
          // while(nums[left]==nums[left+1]&&left<right)left++;
          left++;
          right--;
       }
   }
  }
  return result;
   }
};

这个版本错误在于去重操作有误 我最开始写的时候 在每一次left和right要移动时,就进行一个去重,会导致数组越界,但需要在找到一个满足条件的结果之后再进行去重

正确版本
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
    vector<vector<int>>result;
    int left=0,right=0;
    //先对数组进行排序
   sort(nums.begin(),nums.end());
   for(int i=0;i<nums.size();i++){
    if(nums[i]>0)return result; //如果第一个元素大于0,三个元素之和不可能大于0
    if(i>0&&nums[i]==nums[i-1])continue;
    left=i+1;
    right=nums.size()-1;
    while(right>left){
        if(nums[i]+nums[right]+nums[left]>0){
            right--;  
        }else if(nums[i]+nums[right]+nums[left]<0){
            left++;
        }else{
           result.push_back(vector<int>{nums[i],nums[left],nums[right]});
            while(nums[right]==nums[right-1]&&left<right) right--;
           while(nums[left]==nums[left+1]&&left<right)left++;
           left++;
           right--;
        }
    }
   }
   return result;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2297362.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Unity学习part1

课程为b站【Unity教程】零基础带你从小白到超神 1、脚本执行顺序 unity的脚本执行顺序不像blender的修改器那样按顺序执行&#xff0c;而是系统默认给配置一个值&#xff0c;值越小&#xff0c;执行顺序越靠前&#xff08;注意&#xff0c;这个顺序是全局生效的&#xff09; …

【AI论文】10亿参数大语言模型能超越405亿参数大语言模型吗?重新思考测试时计算最优缩放

摘要&#xff1a;测试时缩放&#xff08;Test-Time Scaling&#xff0c;TTS&#xff09;是一种通过在推理阶段使用额外计算来提高大语言模型&#xff08;LLMs&#xff09;性能的重要方法。然而&#xff0c;目前的研究并未系统地分析策略模型、过程奖励模型&#xff08;Process …

Ubuntu20.04上搭建nginx正向代理提供上网服务

背景&#xff1a;公司很多电脑因软件管控问题不得不禁止设备上网&#xff0c;现需搭建上网代理服务器提供给这些用户使用。 操作系统&#xff1a;ubuntu20.04 工具&#xff1a;nginx-1.25.4 1、下载nginx安装包及依赖 由于nginx默认只持支持转发http协议&#xff0c;所以如…

使用 PDF SDK 通过页面分割和数据提取对建筑图纸进行分类

一家专门从事设计和建设的建筑公司对大量多页建筑 PDF 图纸进行分类&#xff0c;从而提高协作和运营效率。 这类公司通常承担多个建筑设计项目&#xff0c;每个项目包含多个设计图纸&#xff0c;如详细的结构计划、电气与水管计划、机械计划等。如果项目图纸可以在上传后自动分…

Linux命名管道与共享内存

命名管道与共享内存 命名管道介绍和基本使用 理解了匿名管道后&#xff0c;命名管道的理解就会变得容易。在前面使用匿名管道时可以发现&#xff0c;之所以可以匿名是因为由父进程创建&#xff0c;子进程拷贝所以子进程和父进程都可以看到这个管道。但是如果对于任意两个进程…

使用 Notepad++ 编辑显示 MarkDown

Notepad 是一款免费的开源文本编辑器&#xff0c;专为 Windows 用户设计。它是替代记事本&#xff08;Notepad&#xff09;的最佳选择之一&#xff0c;因为它功能强大且轻量级。Notepad 支持多种编程语言和文件格式&#xff0c;并可以通过插件扩展其功能。 Notepad 是一款功能…

解锁Rust:融合多语言特性的编程利器

如果你曾为理解Rust的特性或它们之间的协同工作原理而苦恼,那么这篇文章正是为你准备的。 Rust拥有许多令人惊叹的特性,但这些特性并非Rust所独有。实际上,Rust巧妙地借鉴了众多其他语言的优秀特性,并将它们融合成了一个完美的整体。深入了解Rust这些重要特性的来源以及它是…

zyNo.23

SQL注入漏洞 1.SQL语句基础知识 一个数据库由多个表空间组成&#xff0c;sql注入关系到关系型数据库&#xff0c;常见的关系型数据库有MySQL,Postgres,SQLServer,Oracle等 以Mysql为例&#xff0c;输入 mysql-u用户名-p密码 即可登录到MySQL交互式命令行界面。 既然是…

visual studio 在kylin v10上跨平台编译时c++标准库提示缺少无法打开的问题解决

情况1&#xff1a;提示无法打开 源文件 "string"之类导致无法编译 情况2:能编译&#xff0c;但无法打开这些库文件或标准库使用提示下划红色问题 解决方案&#xff1a; 一、通过工具->选项->跨平台里&#xff0c;在“远程标头IntelliSense管理器”更新下载一下…

Spring Cloud — 深入了解Eureka、Ribbon及Feign

Eureka 负责服务注册与发现&#xff1b;Ribbon负责负载均衡&#xff1b;Feign简化了Web服务客户端调用方式。这三个组件可以协同工作&#xff0c;共同构建稳定、高效的微服务架构。 1 Eureka 分布式系统的CAP定理&#xff1a; 一致性&#xff08;Consistency&#xff09;&am…

2025年SEO工具有哪些?老品牌SEO工具有哪些

随着2025年互联网的发展和企业线上营销的日益重要&#xff0c;SEO&#xff08;搜索引擎优化&#xff09;逐渐成为了提高网站曝光率和流量的重要手段。SEO的工作不仅仅是简单地通过关键词优化和内容发布就能够实现的&#xff0c;它需要依赖一系列专业的SEO工具来帮助分析、监测和…

LabVIEW显微镜成像偏差校准

在高精度显微镜成像中&#xff0c;用户常常需要通过点击图像的不同位置&#xff0c;让电机驱动探针移动到指定点进行观察。然而&#xff0c;在实际操作中&#xff0c;经常会遇到一个问题&#xff1a;当点击位于图像中心附近的点时&#xff0c;探针能够相对准确地定位&#xff1…

23页PDF | 国标《GB/T 44109-2024 信息技术 大数据 数据治理实施指南 》发布

一、前言 《信息技术 大数据 数据治理实施指南》是中国国家标准化管理委员会发布的关于大数据环境下数据治理实施的指导性文件&#xff0c;旨在为组织开展数据治理工作提供系统性的方法和框架。报告详细阐述了数据治理的实施过程&#xff0c;包括规划、执行、评价和改进四个阶…

AI代码生成器如何重塑前端开发的工作环境

近年来&#xff0c;人工智能&#xff08;AI&#xff09;技术迅猛发展&#xff0c;深刻地改变着各行各业的工作方式。在软件开发领域&#xff0c;AI写代码工具的出现更是掀起了一场革命&#xff0c;尤其对前端开发工程师的工作环境和协作方式产生了深远的影响。本文将深入探讨AI…

Xcode证书密钥导入

证书干嘛用 渠道定期会给xcode证书&#xff0c;用来给ios打包用&#xff0c;证书里面有记录哪些设备可以打包进去。 怎么换证书 先更新密钥 在钥匙串访问中&#xff0c;选择系统。(选登录也行&#xff0c;反正两个都要导入就是了)。 mac中双击所有 .p12 后缀的密钥&#xff…

Python 基于 OpenCV 的人脸识别上课考勤系统(附源码,部署教程)

博主介绍&#xff1a;✌2013crazy、10年大厂程序员经历。全网粉丝12W、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&a…

TikTok网页版访问受限?一文解析解决方案

TikTok网页版是许多用户用来浏览视频、管理账号和发布内容的重要工具。然而&#xff0c;部分用户可能会遇到无法打开TikTok网页版的问题&#xff0c;如页面加载失败、显示网络错误或提示访问受限。本文将帮助你快速排查问题&#xff0c;并提供解决方案&#xff0c;让你顺利访问…

【vs2022配置cursor】

Cursor搭配cmake实现C程序的编译、运行和调试的参考地址 cursor下载地址 第一步&#xff1a; 电脑上按爪cmake 第二步&#xff1a;cursor 配置 安装中文 第三步环境变量&#xff1a; D:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.35.322…

Redis 的缓存雪崩、缓存穿透和缓存击穿详解,并提供多种解决方案

本文是对 Redis 知识的补充&#xff0c;在了解了如何搭建多种类型的 Redis 集群&#xff0c;并清楚了 Redis 集群搭建的过程的原理和注意事项之后&#xff0c;就要开始了解在使用 Redis 时可能出现的突发问题和对应的解决方案。 引言&#xff1a;虽然 Redis 是单线程的&#xf…

DeepSeek-R1复现方案梳理

open-r1 项目地址&#xff1a;https://github.com/huggingface/open-r1 由huggingface组建&#xff0c;目前刚上线2周&#xff0c;发布了最新进展open-r1/update-1&#xff0c;在MATH-500任务上接近deepseek的指标&#xff0c;可以在open-r1/open-r1-eval-leaderboard查看指标的…