LeetCode三数之和

server/2024/9/23 4:40:44/

题目描述:

给你一个整数数组 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 。

代码

/*** 函数threeSum,接受一个数字数组nums作为参数,返回所有和为0的三元组数组。* * @param {number[]} nums 数字数组* @return {number[][]} 所有和为0的三元组数组*/
var threeSum = function (nums) {// 首先对数组进行排序,使用升序let arr = nums.sort((a, b) => a - b);// 初始化结果数组let result = [];// 临时变量,用于存储中间结果let tmp, left, right;// 循环遍历数组中的所有数for (let i = 0; i < arr.length; i++) {// 如果当前元素大于0,由于数组是升序排列的,后面的元素都会更大,不可能找到和为0的三元组if (arr[i] > 0) break;// 如果当前元素与前一个元素相同,跳过当前循环,避免找到重复的三元组while (arr[i] == arr[i - 1]) i++;// 计算当前元素的补数,即需要找到两个数,使得它们与当前元素相加等于0tmp = 0 - arr[i];// 初始化左指针,从当前元素的下一个位置开始left = i + 1;// 初始化右指针,从数组的最后一个元素开始right = arr.length - 1;// 使用左右指针寻找和为0的三元组while (left < right) {// 如果左右指针所指的元素之和等于补数,说明找到了一个三元组if (arr[left] + arr[right] == tmp) {let tmparr = [];// 将当前的三元组添加到临时数组中tmparr.push(arr[i], arr[left], arr[right]);// 将临时数组添加到结果数组中result.push(tmparr);// 跳过重复的left指针元素while (left < right && arr[left] == arr[left + 1]) left++;// 跳过重复的right指针元素while (left < right && arr[right] == arr[right - 1]) right--;// 移动指针,继续寻找下一个可能的三元组left++;right--;} // 如果左右指针所指的元素之和大于补数,说明需要减小和,移动right指针向左else if (arr[left] + arr[right] > tmp) {right--;}// 如果左右指针所指的元素之和小于补数,说明需要增大和,移动left指针向右else if (arr[left] + arr[right] < tmp) {left++;}}}// 返回结果数组return result;
};

代码主要逻辑

  1. 排序:首先对输入数组nums进行排序,这样可以通过比较当前元素与0的关系来确定是否需要继续搜索。

  2. 初始化:定义一个空数组result来存储找到的三元组。

  3. 遍历数组:使用一个for循环遍历数组,其中i是当前考虑的元素的索引。

  4. 终止条件:如果当前元素nums[i]大于0,由于数组已排序,后面的元素也会大于0,因此不可能找到和为0的三元组,直接返回结果。

  5. 跳过重复元素:如果当前元素与前一个元素相同,跳过当前循环,避免找到重复的三元组。

  6. 左右指针:使用两个指针leftright,分别指向当前元素的下一个位置和数组的最后一个元素。

  7. 寻找三元组:在while循环中,通过移动leftright指针来寻找和为0的三元组。

  8. 添加三元组:如果找到和为0的三元组,将其添加到结果数组中,并更新指针位置,同时跳过重复的元素。

  9. 移动指针:如果三数之和不等于0,根据三数之和与0的比较结果来决定是移动left指针还是right指针。

  10. 返回结果:最后返回包含所有和为0的三元组的数组。

这个算法的时间复杂度是O(n^2),其中n是数组的长度,因为对于每个元素,我们最多进行一次O(n)的双指针搜索。


http://www.ppmy.cn/server/101399.html

相关文章

PostgreSQL的启动过程

PostgreSQL的启动过程 PostgreSQL的启动过程中主要做了以下几件事&#xff1a; 初始化数据目录&#xff1a;如果数据目录是第一次使用&#xff0c;PostgreSQL会进行初始化&#xff0c;创建必要的系统表和目录结构。 读取配置文件&#xff1a;PostgreSQL会读取并解析配置文件&…

鸿萌数据恢复服务:SQL Server 中的 GAM、SGAM、IAM,及数据库损坏的修复方法

天津鸿萌科贸发展有限公司从事数据安全服务二十余年&#xff0c;致力于为各领域客户提供专业的数据恢复、数据备份、网络及终端数据安全等解决方案与服务。 同时&#xff0c;鸿萌是国际主流数据恢复软件(Stellar、UFS、R-Studio、ReclaiMe Pro 等)的授权代理商&#xff0c;为专…

Nginx+Tomcat负载均衡、动静分离群集

Tomcat重要目录 bin: 存放启动和关闭tomcat脚本 conf:存放Tomcat不同的配置文件 doc:存放Tomcat文档 lib&#xff1a;存放Tomcat运行需要的库文件 logs&#xff1a;存放Tomcat执行时的LOG文件 src&#xff1a;存放Tomcat的源代码 webapps&#xff1a;T…

Visual Studio Code 安装与 C/C++ 语言运行总结

​ 大家好&#xff0c;我是程序员小羊&#xff01; 前言&#xff1a; Visual Studio Code&#xff08;简称 VS Code&#xff09;是由微软开发的一款轻量级、强大的代码编辑器&#xff0c;支持多种编程语言和开发框架。由于其丰富的插件生态系统和灵活的配置选项&#xff0c;VS…

Android CheckBox

设置 checkbox 文字与图标的间距 android:layoutDirection"rtl"android:paddingStart"dimen/x15"android:paddingEnd"dimen/x15"注意 是否 设置了 图标按钮的方向

Linux/C 高级——shell脚本

1. shell脚本基础概念 1.1概念 shell使用方式&#xff1a;手动下命令和脚本 脚本本质是一个文件&#xff0c;文件里面存放的是特定格式的指令&#xff0c;系统可以使用脚本解析器翻译或解析指令并执行&#xff08;它不需要编译&#xff09;。 shell脚本本质&#xff1a;shell命…

强!小目标检测全新突破!检测速度快10倍,GPU使用减少73.4%

强&#xff01;小目标检测全新突破&#xff0c;提出Mamba-in-Mamba结构&#xff0c;通过内外两层Mamba模块&#xff0c;同时提取全局和局部特征&#xff0c;实现了检测速度快10倍&#xff0c;GPU使用减少73.4&#xff05;的显著效果&#xff01; 【小目标检测】是近年来在深度…

Linux下简单快捷高效的用五笔打出特殊符号(含Emoji)-基于fcitx5

Linux下简单快捷高效的用五笔打出特殊符号&#xff08;含Emoji&#xff09;-基于fcitx5 官网地址&#xff1a;https://github.com/devome/wubi-symbols/tree/main 如何使用&#xff1f;以Fcitx5为例。 1. 下载特殊符号库 下载 output 下面的文件&#xff0c;或者直接从 rel…