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

【算法】梦破碎之地---三数之和

相信大家都有做过两数之和,

题目链接: 15. 三数之和 - 力扣(LeetCode)

在文章的开始让我们回顾一下三数之和吧!

题目描述:

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != 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 。

解题思路:

首先要使形如a + b +c = 0,我们可以座一层循环,让i表示a,通过双指针表示另外两个数,left-->b,right-->c;在动手解题前一定要对数组做预处理,排序,这样可以避免很多麻烦,我们让i从数组下标第一个元素开始,left取i + 1;right取nums.length - 1;i不动,让两个指针移动,判断sum=a+b+c的值,当sum>0时,证明整体大了需要减小和,故使right--;当sum<0时,证明整体小了需要增大和,故使left++;sum=0即一组解。

整体思路就是这样,当其实有很多细节的地方,尤其是 去重,这也是解本题最关键的地方,我们需要对a b c去重,避免重复解。

对a去重: if(i>0 and nums[i]==nums[i-1])   continue;

对b c去重: if(right > left and nums[right] = nums[right--] )        right--;

                    if  (right > left and nums[left] = nums[left++] )        left++;

上代码:

代码详解可看(强推,简单易懂,细节拉满): 梦破碎的地方!| LeetCode:15.三数之和_哔哩哔哩_bilibili

class Solution {public List<List<Integer>> threeSum(int[] nums) {List<List<Integer>> res = new ArrayList<>();//预处理---》排序Arrays.sort(nums);for(int i=0;i < nums.length;i++){if(nums[i] > 0) break; // 对a去重if(i > 0 && nums[i] == nums[i - 1]){continue;}int left = i + 1;int right = nums.length - 1;// 指针移动条件while(right > left){int sum = nums[i] + nums[left] + nums[right];if(sum > 0){right--;}else if(sum < 0){left++;}else{// 先收获结果集在去重 确保至少收获一个结果集res.add(Arrays.asList(nums[i],nums[left],nums[right]));// 对b c去重 这里需要移动 不能用if做判断会漏解的****while(right > left && nums[left] == nums[left+1]){left++;}while(right > left && nums[right] == nums[right-1]){right--;}right--;left++;}}}return res;}
}

这里在给出一个版本的参考:

如果有朋友实在理解不了的话这里给出一个n数之和的解决方案,直接就是背

c++版本:

class Solution {public:vector<vector<int>> threeSum(vector<int>& nums) {sort(nums.begin(), nums.end());// n 为 3,从 nums[0] 开始计算和为 0 的三元组return nSumTarget(nums, 3, 0, 0);}/* 注意:调用这个函数之前一定要先给 nums 排序 */// n 填写想求的是几数之和,start 从哪个索引开始计算(一般填 0),target 填想凑出的目标和vector<vector<int>> nSumTarget(vector<int>& nums, int n, int start, int target) {int sz = nums.size();vector<vector<int>> res;// 至少是 2Sum,且数组大小不应该小于 nif (n < 2 || sz < n) return res;// 2Sum 是 base caseif (n == 2) {// 双指针那一套操作int lo = start, hi = sz - 1;while (lo < hi) {int sum = nums[lo] + nums[hi];int left = nums[lo], right = nums[hi];if (sum < target) {while (lo < hi && nums[lo] == left) lo++;} else if (sum > target) {while (lo < hi && nums[hi] == right) hi--;} else {res.push_back({left, right});while (lo < hi && nums[lo] == left) lo++;while (lo < hi && nums[hi] == right) hi--;}}} else {// n > 2 时,递归计算 (n-1)Sum 的结果for (int i = start; i < sz; i++) {vector<vector<int>>sub = nSumTarget(nums, n - 1, i + 1, target - nums[i]);for (vector<int>& arr : sub) {// (n-1)Sum 加上 nums[i] 就是 nSumarr.push_back(nums[i]);res.push_back(arr);}while (i < sz - 1 && nums[i] == nums[i + 1]) i++;}}return res;}
};

java版本:

class Solution {public List<List<Integer>> threeSum(int[] nums) {Arrays.sort(nums);// n 为 3,从 nums[0] 开始计算和为 0 的三元组return nSumTarget(nums, 3, 0, 0);}/* 注意:调用这个函数之前一定要先给 nums 排序 */// n 填写想求的是几数之和,start 从哪个索引开始计算(一般填 0),target 填想凑出的目标和public List<List<Integer>> nSumTarget(int[] nums, int n, int start, int target) {int sz = nums.length;List<List<Integer>> res = new ArrayList<>();// 至少是 2Sum,且数组大小不应该小于 nif (n < 2 || sz < n) return res;// 2Sum 是 base caseif (n == 2) {// 双指针那一套操作int lo = start, hi = sz - 1;while (lo < hi) {int sum = nums[lo] + nums[hi];int left = nums[lo], right = nums[hi];if (sum < target) {while (lo < hi && nums[lo] == left) lo++;} else if (sum > target) {while (lo < hi && nums[hi] == right) hi--;} else {res.add(new ArrayList<>(Arrays.asList(left, right)));while (lo < hi && nums[lo] == left) lo++;while (lo < hi && nums[hi] == right) hi--;}}} else {// n > 2 时,递归计算 (n-1)Sum 的结果for (int i = start; i < sz; i++) {List<List<Integer>>sub = nSumTarget(nums, n - 1, i + 1, target - nums[i]);for (List<Integer> arr : sub) {// (n-1)Sum 加上 nums[i] 就是 nSumarr.add(nums[i]);res.add(arr);}while (i < sz - 1 && nums[i] == nums[i + 1]) i++;}}return res;}
}

相关文章:

【算法】梦破碎之地---三数之和

相信大家都有做过两数之和&#xff0c; 题目链接&#xff1a; 15. 三数之和 - 力扣&#xff08;LeetCode&#xff09; 在文章的开始让我们回顾一下三数之和吧&#xff01; 题目描述&#xff1a; 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], …...

c语言如何将一个文本内容复制到另外一个文本里

c语言如果要把一个文本文件的文件复制到另外一个文件里&#xff0c;代码如下 #include<stdio.h>int main() {FILE *fp1,*fp2;char a;fp1fopen("D://cyy//aaa.txt","r");fp2fopen("ccc.cpu","w");while(a!EOF){afgetc(fp1);fput…...

JavaScript基础(九)

冒泡排序 用例子比较好理解: var arry[7,2,6,3,4,1,8]; //拿出第一位数7和后面依次比较&#xff0c;遇到大的8就换位&#xff0c;8再与后面依次比较&#xff0c;没有能和8换位的数&#xff0c;再从下一位2依次与下面的数比较。 console.log(排列之前&#xff1a;arry); for (…...

决策树最优属性选择

本文以西瓜数据集为例演示决策树使用信息增益选择最优划分属性的过程 西瓜数据集下载&#xff1a;传送门 首先计算根节点的信息熵&#xff1a; 数据集分为好瓜、坏瓜&#xff0c;所以|y|2根结点包含17个训练样例&#xff0c;其中好瓜共计8个样例&#xff0c;所占比例为8/17坏…...

NER 数据集格式转换

NER 数据集格式 格式一 某些地方的数据和标签拆成两个文件了 sentences.txt 如 何 解 决 足 球 界 长 期 存 在 的 诸 多 矛 盾 &#xff0c; 重 振 昔 日 津 门 足 球 的 雄 风 &#xff0c; 成 为 天 津 足 坛 上 下 内 外 到 处 议 论 的 话 题 。 该 县 一 手 抓 农 业…...

【LinuxC语言】utime函数

文章目录 前言函数原型参数`struct utimbuf`返回值示例代码总结前言 utime函数在C语言中用于更改文件的访问时间(access time, atime)和修改时间(modification time, mtime)。这是一个POSIX标准的函数,常用于更新文件的时间戳,而不必实际修改文件的内容。 函数原型 #in…...

Cannot invoke an object which is possibly ‘undefined‘

这是ts中的错误提示&#xff1a; Cannot invoke an object which is possibly undefined 报错场景&#xff1a; 定义interface接口的时候sayHi方法使用的是可选属性&#xff0c;可以有可以没有&#xff0c; 当在实际方法中调用sayHi方法的时候报错了&#xff0c; 问&#xff…...

C++ 计时器

文章目录 一、简介二、实现代码2.1 windows平台2.2 C标准库 三、实现效果 一、简介 有时候总是会用到一些计时的操作&#xff0c;这里也整理了一些代码&#xff0c;包括C标准库以及window自带的时间计算函数。 二、实现代码 2.1 windows平台 StopWatch.h #ifndef STOP_WATCH_H…...

notepad++ 批量转所有文件编码格式为UTF-8

1、安装notepad及PythonScript_3.0.18.0插件 建议两者都保持默认路径安装x64版本&#xff1a; 阿里云盘分享https://www.alipan.com/s/xVUDpY8v5QL安装好后如下图&#xff1a; 2、new Script&#xff0c;新建脚本&#xff0c;文件名为ConvertEncoding 3、自动打开脚本&#xff…...

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-16讲 EPIT定时器

前言&#xff1a; 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM&#xff08;MX6U&#xff09;裸机篇”视频的学习笔记&#xff0c;在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…...

【只会for循环? 来看下, Nodejs中典型的5种循环方式】

Nodejs中的&#xff0c;除了经典的for循环 , 其实还有几种好用的循环方式&#xff0c; 并有典型的使用场景。下面来一起看下&#x1f447;&#x1f3fb; 5种循环用法 For Loop&#xff1a;这是最常见的循环方式&#xff0c;适用于你知道循环次数的情况。 for (let i 0; i &…...

Java基础(三)- 多线程、网络通信、单元测试、反射、注解、动态代理

多线程基础 线程&#xff1a;一个程序内部的一条执行流程&#xff0c;只有一条执行流程就是单线程 java.lang.Thread代表线程 主线程退出&#xff0c;子线程存在&#xff0c;进程不会退出 可以使用jconsole查看 创建线程 有多个方法可以创建线程 继承Thread类 优点&#x…...

WordPress建站公司模板免费下载

WordPress建站公司 适合提供WordPress建站服务的公司或个体(个人)工作室使用的WordPress建站公司主题模板。 演示 https://www.jianzhanpress.com/?p545 https://www.wpicu.com/jianzhan/ 下载 链接: https://pan.baidu.com/s/11trlwUJq_lW81R_acq4ilA 提取码: r19i...

金融信贷风控基础知识

一、所谓风控(What && Why) 所谓风控&#xff0c;可以拆解从2个方面看&#xff0c;即 风险和控制 风险(what) 风险 这里狭隘的特指互联网产品中存在的风险点&#xff0c;例如 账户风险 垃圾注册账号账号被泄露盗用 交易支付风险 刷单&#xff1a;为提升卖家店铺人气…...

Web Server项目实战4-服务器编程基本框架和2种高效的事件处理模式

服务器编程基本框架 虽然服务器程序种类繁多&#xff0c;但其基本框架都一样&#xff0c;不同之处在于逻辑处理 模块功能I/O处理单元处理客户连接&#xff0c;读写网络数据逻辑单元业务进程或线程网络存储单元数据库、文件或缓存请求队列各单元之间的通信方式 I/O 处理单元是…...

。。。。。

...

RPC原理技术

RPC原理技术 背景介绍起源组件实现工作原理 背景 本文内容大多基于网上其他参考文章及资料整理后所得&#xff0c;并非原创&#xff0c;目的是为了需要时方便查看。 介绍 RPC&#xff0c;Remote Procedure Call&#xff0c;远程过程调用&#xff0c;允许像调用本地方法一样调…...

开源大模型与闭源大模型:技术哲学的较量

目录 前言一、 开源大模型的优势1. 社区支持与合作1.1 全球协作网络1.2 快速迭代与创新1.3 共享最佳实践 2. 透明性与可信赖性2.1 审计与验证2.2 减少偏见与错误2.3 安全性提升 3. 低成本与易访问性3.1 降低研发成本3.2 易于定制化3.3 教育资源丰富 4. 促进标准化5. 推动技术进…...

buuctf的RSA(二)

1.RSA 知道 flag.enc 和 pub.key&#xff0c;典型的加密、解密 将pub,key 改为pub.txt 打开后发现公钥 在RSA公私钥分解 Exponent、Modulus&#xff0c;Rsa公私钥指数、系数(模数)分解--查错网 进行解密 得到e65537 n8693448229604811919066606200349480058890565…...

idm软件是做什么的 IDM是啥软件 idm软件怎么下载 idm软件怎么下载

一、IDM是啥软件 IDM 是由美国 Tonec 公司开发的 Windows 软件&#xff0c;该软件最初于 2005 年发布。IDM全称Internet Download Manager&#xff0c;是一款Windows平台老牌而功能强大的下载加速器&#xff0c;专注于互联网数据下载。这款软件是一款不错的轻量级下载工具&…...

【SpringBoot 】dynamic 动态数据源配置连接池(转)

前言 在复杂的业务场景中&#xff0c;我们经常需要使用多数据源来满足不同的数据访问需求。Dynamic Datasource 为我们提供了一种灵活切换不同数据源的解决方案。但是多数据源配置连接池 以及说明文档都是收费的。 本篇博文将详细介绍如何配置和优化 Dynamic Datasource 的连接…...

数据库课程设计案例:基于深度感知的智能仓储管理系统

数据库课程设计案例&#xff1a;基于深度感知的智能仓储管理系统 每次路过大型物流仓库&#xff0c;看到那些高耸的货架和穿梭的叉车&#xff0c;我总会想&#xff0c;他们是怎么知道哪个货位是满的&#xff0c;哪个是空的&#xff1f;靠人工盘点&#xff1f;那得累死。靠传统…...

c++ 字符大小写转化

#include <iostream> using namespace std;int main() {char a;cin >> a;//a-z-97-122//A-Z-65-90//差32//小写转大写 if(97<(int)a && (int)a<122){a(int)a-32;cout << a; return 0; }//大写转小写 if(65<(int)a && (int)a<90)…...

文艺复兴,什么是XSS,常见形式(二)

前言 本文将继续介绍XSS的常见形状&#xff0c;依赖于portswigger提供的免费Lab环境&#xff0c;将重点介绍关于使用脚本来进行表单XSS验证以及针对标签的模糊测试。 Lab: Stored DOM XSS 这是一个存储型的DOM类的XSS&#xff0c;具体的是当你将内容提交到评论区&#xff0c…...

OpenClaw自动化测试:Qwen3.5-9B执行Python脚本与结果校验

OpenClaw自动化测试&#xff1a;Qwen3.5-9B执行Python脚本与结果校验 1. 为什么选择OpenClaw做自动化测试&#xff1f; 去年接手一个数据清洗工具链项目时&#xff0c;我遇到了一个典型痛点&#xff1a;每次代码更新后&#xff0c;都需要手动执行十几个测试用例&#xff0c;比…...

OpenClaw+QwQ-32B科研助手:文献摘要与笔记自动整理

OpenClawQwQ-32B科研助手&#xff1a;文献摘要与笔记自动整理 1. 为什么需要AI科研助手&#xff1f; 作为一名经常需要阅读大量文献的研究者&#xff0c;我发现自己长期陷入"文献管理困境"&#xff1a;下载的PDF堆积如山&#xff0c;重要信息散落在不同标注工具里&…...

FastJson内存泄漏实战:我是如何用MAT工具定位到IdentityHashMap这个坑的

FastJson内存泄漏深度剖析&#xff1a;从MAT工具实战到IdentityHashMap陷阱破解 凌晨三点&#xff0c;手机突然响起刺耳的告警声——生产环境某核心服务的堆内存使用率突破95%。作为值班工程师&#xff0c;我瞬间清醒过来。这不是普通的OOM&#xff0c;而是一场持续增长的内存…...

先瑞达2025年年报:营收同比增长20.7% 双引擎格局成型迎高质量增长

3月26日晚间&#xff0c;先瑞达医疗&#xff08;6669.HK&#xff09;正式发布截至2025年12月31日的年度业绩报告。报告期内&#xff0c;公司紧扣血管介入治疗领域核心赛道&#xff0c;以技术创新为内核、以全球化布局为抓手、以降本增效为支撑&#xff0c;实现经营业绩的稳健增…...

突破限制:BlenderCompat让Windows 7焕发新活力运行Blender 3.x

突破限制&#xff1a;BlenderCompat让Windows 7焕发新活力运行Blender 3.x 【免费下载链接】BlenderCompat Windows 7 support for Blender 3.x and newer 项目地址: https://gitcode.com/gh_mirrors/bl/BlenderCompat 在3D创作领域&#xff0c;Blender的每一次版本迭代…...

CasRel开源大模型部署教程:一键拉取镜像+5分钟完成SPO推理

CasRel开源大模型部署教程&#xff1a;一键拉取镜像5分钟完成SPO推理 1. 什么是CasRel关系抽取模型 如果你需要从大段文字中自动找出"谁做了什么"、"谁是什么"这样的信息&#xff0c;CasRel模型就是你的得力助手。这个模型专门用来从文本中提取主体-谓语…...