JavaScript刷LeetCode拿offer-双指针技巧(上)

news2024/11/23 3:43:00

一、前言

一般情况下,遍历数组(或者字符串)操作,都是采用单指针从前往后或者从后往前依次访问数组(或者字符串)中的元素。

而对于以下情况,只采用单指针处理,则会徒增时间复杂度和空间复杂度:

  • 例如:找到两个数使得它们相加之和等于目标数,采用单指针处理,则需要嵌套循环,使得时间复杂度增长为 O(n^2);

  • 再例如:翻转数组,采用单指针处理,则需要额外内存空间,使得空间复杂度增长为 O(n);

利用双指针技巧则可以优化上述解决方案:

  • 第一个例子:可以先对采用数组进行排序预处理,再创建前后指针向中间遍历,遍历的时间复杂度为 O(n),整体时间复杂度主要取决于排序算法,通常为 O(nlogn);

  • 第二个列子:一个指针负责遍历,另外一个指针负责交换元素,从而使得空间复杂度为 O(1);

双指针没有复杂的定义,总结起来主要处理两类问题:

  • 将嵌套循环转化为单循环问题

  • 通过指针记录状态,从而优化空间复杂度

下面的实战分析会让你感受双指针的威力。

二、167. 两数之和 II - 输入有序数组

给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。

这道题目采用单指针的做法只能通过嵌套循环枚举所有两数之和的方法来解决,时间复杂度为 O(n^2)。

恰巧本题中的数组已经是有序数组,那么直接创建前后指针:

  • 如果两数之后大于 target,尾指针向前移动;

  • 如果两数之和小于 target,头指针向后移动;

在这里插入图片描述

上述代码利用双指针技巧成功地将时间复杂度降低为 O(n)。

三、344. 反转字符串

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。

本题采用单指针的方法,需要创建一个额外的数组来保存翻转后的元素,空间复杂度为 O(n)。

利用双指针技巧,则可以在遍历的过程中同时完成交换元素的操作,时间复杂度降低为 O(1)

在这里插入图片描述

相同类型的题目还有:

  • 【345. 反转字符串中的元音字母】

四、141. 环形链表

给定一个链表,判断链表中是否有环。为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。

在链表这种数据结构中,采用前文所说的前后指针并不一定有效(例如单向链表),这种情况下,双指针的表现形式为:快慢指针

快慢指针指的是:设置两个前进方向相同但速度不同的指针。

本题中,设置每次移动一个单位的慢指针和每次移动两个单位的快指针,那么他们必定会在环内相遇:

在这里插入图片描述

参考视频:传送门

相同类型的题目还有:

  • 【26. 删除排序数组中的重复项】

五、125. 验证回文串

给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。说明:本题中,我们将空字符串定义为有效的回文串。

回文字符串问题是双指针的经典应用,同时也是面试题中的常客。

在这里插入图片描述

六、27. 移除元素

给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度。不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

显而易见的解决方法是通过 while + splice 处理,但是 splice 操作方法是非常耗时的,每次删除元素之后,需要重排数组中的元素,具有相同副作用的操作方法还有 unshift 和 shift 。 (具体可以查看 V8 源码)

相比较下,pop 和 push 则是非常快的操作方法,这里可以采用双指针 + pop 操作方法,进一步优化时间复杂度:

在这里插入图片描述

写在最后

算法作为计算机的基础学科,用 JavaScript 刷,一点也不丢人ε=ε=ε=┏(゜ロ゜;)┛。

本系列文章会分别给出一种算法的3种难度的总结篇(简单难度,中等难度以及困难难度)。在简单难度中,会介绍该算法的基本知识与实现,另外两个难度,着重讲解解题的思路。

如果本文对您有所帮助,可以点赞或者关注来鼓励博主。

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

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

相关文章

统计学习方法 | 概论

一.简介 统计学习是关于计算机基于数据构建概率统计模型并运用模型对数据进行预测与分析的一门学科 1.统计学习方法的步骤 ①得到一个有限的训练数据集合 ②确定学习模型的集合(模型) ③确定模型选择的准则(策略) ④实现求解…

Python的安装与配置(图文教程)

安装Python 想要进行Python开发,首先需要下载和配置Python解释器。 下载Python 访问Python官网: https://www.python.org/点击downloads按钮,在下拉框中选择系统类型(windows/Mac OS/Linux等)选择下载最新版本的Python安装Python 双击下载好的Python…

五款几乎没人知道的小众软件,按需下载

分享是一种神奇的东西,它使快乐增大,它使悲伤减小,坚持分享一些好用的软件给大家。 1.开源分享工具——ShareX ShareX 是一款 Windows 上开源的截图、文件共享和生产力工具,它是一款功能非常强大的分享工具,只要是免…

【算法】可解释机器学习-ZFNet(Datawhale)

可解释机器学习-ZFNetZFNet算法介绍:AlexNet的提出使得大型卷积网络开始变得流行起来,但是人们对于CNN网络究竟为什么能表现这么好,以及怎么样能变得更好尚不清楚。 因此为了解决上述两个问题,ZFNet提出了一种可视化技术&#xff…

如何治理谐波问题?——有源滤波器

安科瑞 华楠 一、谐波的定义 任何一种周期性非正弦波形都可以看成是由若干种频率不同的正弦波合成的,其中频率为工频的波形我们称为基波,大于1 整数倍基波频率的正弦波分量称为谐波。 总谐波畸变由不同频率的分次谐波合成,各次谐波频率与基…

asp写的百度ocr识别文字-通用文字识别(高精度版)源码下载

今天接到一个客户需求,需要用ASP写一个百度OCR文字识别代码,他的程序都是用ASP写的,所以我们也需要用ASP给他实现百度OCR文字识别,我们在百度AI网站上启用了通用文字识别高精度版,利用高精度板来实现它的业务需求。在上…

【C++】泛型编程 _函数模板和类模板的基本使用

1.泛型编程 如何实现一个通用的交换函数?这在C语言中是无法实现的,但是C却可以。 C语言一次只能实现一个类型的交换: void Swap(int& left, int& right) {int temp left;left right;right temp; } void Swap(double& left, …

计算机毕设Python+Vue学生信息管理系统 (程序+LW+部署)

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

关于小程序订单中心页设置的公告

为进一步规范小程序交易生态、提升用户购物体验、满足用户在有交易的小程序中便捷查看订单信息的诉求,自2022年12月31日起,对于有“选择商品/服务-下单-支付”功能的小程序,需按照平台制定的规范,在小程序内设置订单中心页。 开发…

创建DataFrame()对象--Pandas

1. DataFrame DateFrame对象是Pandas最常用的数据结构,是由不同类型的列组成的二维数据表结构,类似于EXCEL表,语法格式如下: pandas.DataFrame(dataNone, indexNone, columnsNone, dtypeNone, copyNone)1.1 函数参数:data 参数…

计算机操作系统笔记总结:Part2 进程与线程

文章目录1 进程1.1 进程的概念、组成与特征1.2 进程的状态与转换1.3 进程的组织1.4 进程控制1.5 进程通信2 线程与多线程模型2.1 线程的概念2.2 线程的实现方式2.3 多线程模型2.4 线程的状态与转换3 处理机调度3.1 调度的三个层次3.2 进程的挂起态与七状态模型3.3 进程调度3.3.…

[附源码]Nodejs计算机毕业设计健身房预约平台Express(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置: Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术: Express框架 Node.js Vue 等等组成,B/S模式 Vscode管理前后端分…

【浙工商期末报告】研一Python期末作业B题(思路分享+源代码分享+原报告分享)

目录:研一Python期末作业B题(思路分享)一、题目介绍1.1 A题1.2 B题二、B题思路讲解2.1 问题的引入2.2 不平衡数据集2.2.1 不平衡数据的实例2.2.2 不平衡数据集导致的问题2.2.3 不平衡数据集的主要处理方法2.2.4 不平衡(均衡&#…

数据结构实验大作业(将之前预测ACM获奖的模型搬到Vue和django上)

目录 前言 成品展示(UI写的确实有点糊弄,太懒了不想弄了) Vue部分 App.vue(中间感觉还行,不算难看) result组件: 路由: Django部分 view functionset(自己建的&am…

Java岗最全面试攻略,吃透这些技术栈Offer拿到手软

前言 我分享的这份 Java 后端开发面试总结包含了 JavaOOP、Java 集合容器、Java 异常、并发编程、Java 反射、Java 序列化、JVM、Redis、Spring MVC、MyBatis、MySQL 数据库、消息中间件 MQ、Dubbo、Linux、ZooKeeper、 分布式 &数据结构与算法等 25 个专题技术点&#xff…

重学React之高阶函数(Higher Order Function)

高阶函数(Higher Order Function) “把函数传给一个函数,返回另一个函数”,就是高阶函数。 高阶函数是一个常见的函数,它接受其他函数作为参数,然后返回一个函数。听起来很绕,但是这是个很常见的模式,比如有一个ajax函数,可以传一个callback作为处理函数,然后调用的地…

设计模式原则 - 里氏替换原则(四)

一 背景: 里氏替换原则是针对继承的。介绍前先聊聊继承性的特点 继承优势 提高代码的复用性(每个子类有拥有父类的属性和方法)提高代码的可扩展性 继承劣势 继承是侵入性的(只要继承,就必须拥有父类的属性和方法&…

Linux中的Chrony时间同步服务

目录 一、时间同步 1.概念 2.时间同步在运维工作中的作用 3.时间同步完成方法 (1)NTP时间服务(centos 6 ) (2)Chrony时间服务 二、Chrony时间服务 1.Chrony介绍 2.Chrony的优点 三、Chrony安装 …

linux基础学习-基本命令

基本命令 拷贝和移动 tree[目录名]:以树状图列出文件目录结构 -d:只显示目录cp 源文件 目标文件:复制文件或者目录 -f:已存在的目标文件直接覆盖,不会提示-i:覆盖文件前提示-r:若给出的源文件是…

SQLMAP高级用法

目录 前言 一、语法 1.利用google浏览器进行批量扫描 2.针对http请求头进行扫描 3.写入shell的几种方法 4.挂代理的方式 二、演示 1.批量扫描谷歌代理 2.http请求ua扫描 3.写入shell(一) 4.写入shell(二) 三、小结 前…