前端算法题----三数求和问题

算法题讲解

真题描述:

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

思路分析

首先大家要记住一个结论:几乎所有的求和问题,都可以转化为求差问题

接下来就我们可以把求和问题变成求差问题——我们先固定其中一个数,在剩下的数中寻找是否有两个数和这个固定数相加是等于0的。虽然这道题看起来好像需要三层循环才能解决的样子,但是我们可以使用双指针法,可以大大提高定位效率。

注意:双指针法用在涉及求和、比大小类的数组题目里的前提是,该数组必须有序。否则双指针根本无法帮助我们缩小定位的范围,压根没有意义。因此这道题的第一步是将数组排序。

然后,遍历给定数组。对于当前遍历到的数字,将其固定,然后用左指针指向该数字后面一个位置,右指针指向数组末尾。接下来,让左右指针从起点和终点开始向中间靠拢,每次移动一个位置,并计算两个指针指向数字之和加上固定的数字之后是否等于0。如果等于0,则表示找到了一个目标组合;否则,根据计算结果分为两种情况:

  • 相加之和大于0,说明右侧的数偏大了,因此需要将右指针左移。
  • 相加之和小于0,说明左侧的数偏小了,因此需要将左指针右移。

需要注意的是,题目要求找出不重复的三元组,因此在实现时需要处理重复元素的情况。

方法一

代码

/*** @param {number[]} nums1* @param {number} m* @param {number[]} nums2* @param {number} n* @return {void} Do not return anything, modify nums1 in-place instead.*/
const merge = function(nums1, m, nums2, n) {// 初始化两个指针的指向,初始化 nums1 尾部索引klet i = m - 1, j = n - 1, k = m + n - 1// 当两个数组都没遍历完时,指针同步移动while(i >= 0 && j >= 0) {// 取较大的值,从末尾往前填补if(nums1[i] >= nums2[j]) {nums1[k] = nums1[i] i-- k--} else {nums1[k] = nums2[j] j-- k--}}// nums2 留下的情况,特殊处理一下 while(j>=0) {nums1[k] = nums2[j]  k-- j--}
};

这个函数的时间复杂度为O(m+n),空间复杂度为O(1)。

代码讲解:
  • 首先初始化三个指针:i 指向 nums1 的末尾元素,j 指向 nums2 的末尾元素,k 指向合并后的 nums1 的末尾。
  • ij 都大于等于 0 时,进行循环,同时移动指针 ij,每次取 nums1[i]nums2[j] 中较大的值填入 nums1[k] 中,并将指针 ik 同时向前移动,或者将 nums2[j] 填入 nums1[k] 中,并将指针 jk 同时向前移动。
  • 如果 nums2 中还有元素未被处理,就需要将其全部填入 nums1 中。
  • 最终,nums1 中存储的就是合并后的有序数组。

双指针法中的“对撞指针”法

“对撞指针法”
是一种特殊的双指针形态,通常应用于“有序数组”问题中。当我们看到有序数组这个关键条件时,就应该尝试使用对撞指针解决问题。

如果题目中没有给出数组有序的条件,我们可以手动对数组进行排序,再尝试使用对撞指针。对撞指针可以帮助我们缩小问题的范围,以便于把时间花在真正有意义的计算和对比上,同时降低问题的复杂度,提高解题速度。在“三数求和”问题中,我们可以用两个指针“画地为牢”圈出一个范围,范围以外的值不是太大就是太小、直接被排除在我们的判断逻辑之外,从而节省计算时间,提高解题效率。

总结

  • 双指针法,它可以做到空间换时间;另一方面,它也可以帮我们降低问题的复杂度
  • 双指针法用在涉及求和、比大小类的数组题目里时,大前提往往是,该数组必须有序。否则双指针根本无法帮助我们缩小定位的范围,压根没有意义
  • 当我们看到有序数组这个关键条件时,就应该尝试使用对撞指针解决问题。
写在最后

伙伴们,如果你觉得我写的文章对你有帮助就给zayyo点一个赞👍或者关注➕都是对我最大的支持。当然你也可以加我微信:IsZhangjianhao,邀你进我的前端学习交流群,一起学习前端,成为更优秀的工程师~

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

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

相关文章

Applied Spatial Statistics(七):Python 中的空间回归

Applied Spatial Statistics(七):Python 中的空间回归 本笔记本演示了如何使用 pysal 的 spreg 库拟合空间滞后模型和空间误差模型。 OLS空间误差模型空间滞后模型三种模型的比较探索滞后模型中的直接和间接影响 import numpy as np impor…

【html】用html写一个博物馆首页

效果图&#xff1a; 二级导航&#xff1a; 源码&#xff1a; <!DOCTYPE html> <html lang"zh"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><l…

江协科技51单片机学习- p14 调试LCD1602显示屏

前言&#xff1a; 本文是根据哔哩哔哩网站上“江协科技51单片机”视频的学习笔记&#xff0c;在这里会记录下江协科技51单片机开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了江协科技51单片机教学视频和链接中的内容。 引用&#xff1a; 51单片机入门教程-2…

算法框架:冷部署实现优雅退出

冷部署实现优雅退出&#xff1a;背景与解决方案 在微服务架构中&#xff0c;服务的更新和部署是日常运维中不可避免的任务。然而&#xff0c;传统的冷部署方法往往会直接停止旧服务并启动新服务&#xff0c;这样会导致正在处理的请求被中断&#xff0c;进而影响用户体验。为了…

RabbitMQ消息队列 安装及基本介绍

一.MQ介绍 Message Queue &#xff08;MQ&#xff09;是一种跨进程的通信机制&#xff0c;用于在系统之间进行传递消息。MQ作为消息中间件&#xff0c;可以进行异步处理请求&#xff0c;从而减少请求响应时间和解耦 1.1 应用场景 1.1.1 系统之间通过MQ进行消息通信&#xff0…

leetcode 二分查找·系统掌握 x的平方根

题目&#xff1a; 题解 这题可以使用~01~泛型查找在0~x/2的范围内查找答案。 int mySqrt(int x) {long l0,rx,mid;while(l<r){mid(lr1)>>1;if(mid*mid>x)rmid-1;else lmid;}//因为一定有答案所以不用判定是否查找失败return l;}

Docker构建多平台镜像

docker的多架构镜像构建 目前很多服务器都是基于arm架构的&#xff0c;而现在大多数的docker镜像都是基于x86架构的。一种情况就是同样的代码编译成业务包做成镜像需要部署在不同架构的服务器上&#xff0c;这个时候我们就可以使用docker的多平台构建了。 以下操作是在centos7.…

数组、正则表达式、排序

数组 定义&#xff1a;在集合当中指定多个元素&#xff0c;元素的类型可以是整数也可以是字符串&#xff0c;也可以是浮点。 作用&#xff1a;可以一次性定义多个元素&#xff0c;可以为变量赋值提供便利。 数组的定义方法&#xff1a; 数组名 &#xff08;a b c&#xff0…

深入探索 Nuxt3 Composables:掌握目录架构与内置API的高效应用

title: 深入探索 Nuxt3 Composables&#xff1a;掌握目录架构与内置API的高效应用 date: 2024/6/23 updated: 2024/6/23 author: cmdragon excerpt: 摘要&#xff1a;“本文深入探讨了Nuxt3 Composables&#xff0c;重点介绍了其目录架构和内置API的高效应用。通过学习本文&…

pcl::PointXYZRGBA造成点云无法显示

如果pcd文件没有rgba信息&#xff0c;使用pcl::PointXYZRGBA类型打开会提示以下信息&#xff1a; Failed to find match for field rgba另外&#xff0c;显示出来的点云是黑色&#xff0c;如果使用默认背景色为黑色&#xff0c;就无法显示点云了。 如果设置其它背景色&#xf…

服务器防御ddos攻击

硬件层面&#xff1a; 1、高性能防火墙能有效过滤ddos攻击&#xff0c;可以有效的提高网络的抗攻击能力 2、使用流量清洗设备&#xff08;或者ddos防护设备&#xff09;可以过滤攻击流量&#xff0c;可以保护网站和服务器正常运行 软件层面&#xff1a; 1、 隐藏服务器真实IP 2…

命名冲突常见的领域

命名冲突确实是指在不同的来源或上下文中&#xff0c;同一实体&#xff08;可以是对象、变量、函数、类、文件等&#xff09;具有不同的名称。 在编程中&#xff0c;命名冲突可能发生在以下情况&#xff1a; 变量和函数重名&#xff1a;在不同的作用域或模块中&#xff0c;变量…

视频监控平台:支持交通部行业标准JT/T905协议(即:出租汽车服务管理信息系统)的源代码的函数和功能介绍及分享

目录 一、视频监控平台介绍 &#xff08;一&#xff09;概述 &#xff08;二&#xff09;视频接入能力介绍 &#xff08;三&#xff09;功能介绍 二、JT/T905协议介绍 &#xff08;一&#xff09;概述 &#xff08;二&#xff09;主要内容 1、设备要求 2、业务功能要求…

[最全]设计模式实战(一)UML六大原则

UML类图 UML类图是学习设计模式的基础,学习设计模式,主要关注六种关系。即:继承、实现、组合、聚合、依赖和关联。 UML类图基本用法 继承关系用空心三角形+实线来表示。实现接口用空心三角形+虚线来表示。eg:大雁是最能飞的,它实现了飞翔接口。 关联关系用实线箭头来表示…

OOM日志分析

目录 1. 日志分析2. MAT 工具2.1 日志打印方式2.1.1 HeapDumpOnOutOfMemoryError&#xff08;推荐&#xff09;2.1.2 jmp 命令 2.2 MAT分析方式2.2.1 饼图分析2.2.2 树形图分析2.2.2 泄漏疑点 3. 优化 首先说一下结论&#xff1a;通过MAT工具分析才是最精准的&#xff0c;直接通…

2025秋招NLP算法面试真题(二)-史上最全Transformer面试题:灵魂20问帮你彻底搞定Transformer

简单介绍 之前的20个问题的文章在这里&#xff1a; https://zhuanlan.zhihu.com/p/148656446 其实这20个问题不是让大家背答案&#xff0c;而是为了帮助大家梳理 transformer的相关知识点&#xff0c;所以你注意看会发现我的问题也是有某种顺序的。 本文涉及到的代码可以在…

微信小程序建议录音机

在小程序中实现录音机功能&#xff0c;可以通过使用小程序提供的wx.getRecorderManager() API来获取录音管理对象&#xff0c;然后使用这个对象的start()方法来开始录音&#xff0c;使用stop()方法来停止录音&#xff0c;并使用onStop()方法来监听录音的结束。以下是一个简单的…

Spring响应式编程之Reactor核心接口

响应式流的核心接口 核心接口包括&#xff1a;Publisher<T>、Subscriber<T>、Subscription 和 Processo<T,R> &#xff08;1&#xff09;Publisher<T> Publisher接口代表数据流的生产者&#xff0c;根据收到的请求向Subscriber发布数据。接口定义如…

C语言中的字符输入/输出和验证输入

在C语言中&#xff0c;字符输入/输出功能允许程序与用户进行交互&#xff0c;读取用户的输入信息并展示输出结果。同时&#xff0c;验证输入的作用在于确保用户输入的数据符合预期&#xff0c;以提高程序的稳定性和可靠性&#xff0c;防止无效输入引发的错误或异常行为&#xf…

JavaWeb——MySQL:DDL操作库

目录 1.DDL&#xff1a;查询数据库&#xff1b; 1.1 查询数据库 1.2 创建数据库 1.DDL&#xff1a;查询数据库&#xff1b; 具体操作&#xff1a;增 删 查 用 &#xff1b; 1.1 查询数据库 SQL语句&#xff1a;show databases; 由于我创建过一些数据库&#xff0c;我查询的…