【JS】双指针法获得满足三数之和且不重复的三元组

server/2024/10/20 19:09:54/

思路

  1. 排序:首先对数组进行排序,这样可以保证在遍历过程中,相同的元素会相邻,同时也方便使用双指针法。
  2. 避免重复:在遍历过程中,如果当前元素与前一个元素相同,则跳过当前元素,以避免生成重复的三元组。

  3. 边界条件:在开始寻找三元组之前,检查当前元素是否大于0,如果是,则直接返回结果,因为不可能有三数之和为0。

  4. 跳过相同元素:在找到和为0的三元组后,需要跳过所有相同的元素,以避免生成重复的三元组。

详细步骤

  1. 排序数组

    • 使用 nums.sort((a, b) => a - b) 对数组 nums 进行排序。这是一个数值排序,确保数组按照从小到大的顺序排列。
    • 排序的目的是为了后续使用双指针法,这样可以保证在寻找三元组时,如果一个元素比前一个元素大,那么它后面所有的元素都会比前一个元素大,从而避免生成重复的三元组。
  2. 遍历数组

    • 通过 for 循环遍历数组 nums,变量 i 作为当前索引。
    • 在每次迭代开始时,检查当前元素 nums[i] 是否大于0。如果是,由于数组已经排序,所有后续元素都将是正数,不可能找到和为0的三元组,因此直接返回空数组 res
  3. 跳过重复元素

    • 在遍历过程中,如果当前元素 nums[i] 与前一个元素 nums[i-1] 相同,则跳过当前迭代。这是为了避免生成重复的三元组,因为排序后的数组中相同的元素是连续的。
  4. 初始化左右指针

    • 对于每个未跳过的元素 nums[i],初始化两个指针:left 指向 i+1(当前元素之后的下一个元素),right 指向数组的最后一个元素。
    • 这三个索引 ileft 和 right 将用于寻找和为0的三元组。
  5. 双指针法寻找三元组

    • 使用 while 循环,同时移动 left 和 right 指针来寻找和为0的三元组。
    • 在循环中,计算三个指针所指向元素的和:sum = nums[i] + nums[left] + nums[right]
    • 如果 sum < 0,则 left 指针向右移动一位,因为需要一个更大的数来增加总和。
    • 如果 sum > 0,则 right 指针向左移动一位,因为需要一个更小的数来减少总和。
    • 如果 sum === 0,则找到了一个和为0的三元组,将其添加到结果数组 res 中。
  6. 跳过重复的三元组

    • 在找到和为0的三元组后,需要跳过所有重复的元素,以避免生成重复的三元组。
    • 通过两个 while 循环,分别跳过 left 指针左侧和 right 指针右侧的所有重复元素。
  7. 移动指针继续寻找

    • 在每次找到和为0的三元组后,left 和 right 指针分别向右和向左移动一位,继续寻找下一个可能的三元组。
  8. 返回结果

    • 遍历完成后,返回包含所有不重复三元组的结果数组 res

题目

示例代码

javascript">var threeSum = function(nums) {// 初始化结果数组 res,用于存储满足条件的三元组const res = [];// 获取数组的长度const len = nums.length;// 对数组进行从小到大排序nums.sort((a, b) => a - b);// 遍历数组,从索引0开始,直到数组的最后一个元素for (let i = 0; i < len; i++) {// 初始化左右指针,分别指向当前元素之后的元素和数组的最后一个元素let left = i + 1, right = len - 1, iNum = nums[i];// 如果当前元素大于0,那么左右指针的值也大于0,三者和不会为0(数组已排序)if (iNum > 0) return res;// 如果当前元素与前一个元素相同,则跳过,以避免重复的三元组if (i === 0 || nums[i] != nums[i - 1]) {// 使用 while 循环,通过移动左右指针来寻找和为0的三元组while (left < right) {let lNum = nums[left], rNum = nums[right], sum = iNum + lNum + rNum;// 如果三元组的和小于0,移动左指针以增加三元组的和if (sum < 0) left++;// 如果三元组的和大于0,移动右指针以减少三元组的和else if (sum > 0) right--;// 如果三元组的和正好为0,找到了一个满足条件的三元组else {// 将当前三元组添加到结果数组中res.push([iNum, lNum, rNum]);// 移动左指针,跳过所有相同的元素,以避免重复的三元组while (left < right && nums[left] === nums[left + 1]) {left++;}// 移动右指针,跳过所有相同的元素,以避免重复的三元组while (left < right && nums[right] === nums[right - 1]) {right--;}// 移动左指针和右指针,继续寻找下一个可能的三元组left++;right--;}}}}// 返回包含所有满足条件的三元组的结果数组return res;
};

欢迎指正!


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

相关文章

Cloudlog delete_oqrs_line 未授权SQL注入漏洞复现

0x01 产品简介 Cloudlog 是一个自托管的 PHP 应用程序,可让您在任何地方记录您的业余无线电联系人。使用PHP和MySQL构建的基于Web的业余无线电记录应用程序支持从HF到微波的一般站记录任务 0x02 漏洞概述 Cloudlog delete_oqrs_line 接口存在未授权SQL注入漏洞,未经身份验…

nacos的使用

nacos的使用 本专栏的上一篇文章已经部署好了nacos&#xff0c;我们就可以使用nacos做配置中心和注册中心了。 一、配置中心 有了nacos&#xff0c;我们在微服务项目的配置文件里只需要做一些简单的配置就行了&#xff1a;服务名、服务端口、nacos的地址。其余的配置都可以用…

DGCNN代码详解(一)

以下是 knn 和 get_edge_feature 函数的逐行解释: knn 函数 def knn(x, k):inner = -2 * torch.matmul(x.transpose(2, 1), x) # (B, N, N)计算点云之间的内积,用于计算成对距离。 x.transpose(2, 1) 转置张量以便矩阵乘法。 结果是一个大小为 (B, N, N) 的张量。 xx = to…

TCP/UDP通信协议

TCP通讯时序 下图是一次TCP通讯的时序图。TCP连接建立断开。包含大家熟知的三次握手和四次挥手。 在这个例子中&#xff0c;首先客户端主动发起连接&#xff08;connet&#xff09;、发送请求&#xff0c;然后服务器端响应请求&#xff0c;然后客户端主动关闭连接。两条竖线表…

特斯联|日常|Java|后端开发

2024.9.27 一面 整个沟通下来比较轻松&#xff0c;技术问的比较少比较浅。 自我介绍。实习做的什么项目&#xff1f;介绍一下&#xff1f;用过Vue&#xff1f;前端也会吗&#xff1f;大概有多个页面&#xff1f;介绍一下简历项目&#xff1f;你在项目中用到了Redis和MQ&#…

MySQL中什么情况下类型转换会导致索引失效

文章目录 1. 问题引入2. 准备工作3. 案例分析3.1 正常情况3.2 发生了隐式类型转换的情况 4. MySQL隐式类型转换的规则4.1 案例引入4.2 MySQL 中隐式类型转换的规则4.3 验证 MySQL 隐式类型转换的规则 5. 总结 如果对 MySQL 索引不了解&#xff0c;可以看一下我的另一篇博文&…

【Linux】从 fork() 到 exec():理解 Linux 进程程序替换的魔法

1.前言 进程程序替换是指一个进程用另一个新的可执行程序来替换当前正在执行的程序&#xff0c;这个过程通过通过exec系列函数完成。在Linux或UNIX系统中&#xff0c;进程程序替换通常发生在一个进程通过fork()创建了子进程之后&#xff0c;子进程用exec()函数加载和执行另一个…

Kubernetes部署练习

Kubernetes详细笔记 文章目录 Kubernetes 一、Kubernetes介绍 1.1、应用部署方式演变1.2、kubernetes简介1.3、kubernetes组件1.4、kubernetes概念 二、集群环境搭建 2.1、环境规划 2.1.1、集群类型2.1.2、安装方式2.1.3、主机规划 2.2、环境搭建 2.2.1、主机安装2.2.2、环境初…