leetCode-hot100-数组专题之双指针

数组双指针专题

  • 1.同向双指针
    • 1.1例题
      • 26.删除有序数组中的重复项
      • 27.移除元素
      • 80.删除有序数组中的重复项 Ⅱ
  • 2.相向双指针
    • 2.1例题
      • 11.盛最多水的容器
      • 42.接雨水
      • 581.最短无序连续子数组

双指针在算法题中很常见,下面总结双指针在数组中的一些应用,主要分为两类:

1.同向双指针

题目中有原地不适用额外空间等关键词,一般解决方法是定义两个快慢指针:
快指针:用来遍历数组,并进行一些规则匹配
慢指针:用来表示结果数组,即当前符合条件的数组

最后一般是返回慢指针的下标,需要注意的是有时候不能只返回慢指针的下标,可能需要+1,需要根据实际情况分析。

1.1例题

26.删除有序数组中的重复项

思路:
本题设置一个辅助下标指针idx指向数组的第一个元素,然后往后遍历数组,如果遇到了相同的元素就跳过,遇到不同的元素则加入到辅助下标的后一个元素,依次类推,直到遍历数组结束,最后返回idx+1即为所求的长度。详细的视频讲解点击视频讲解-删除有序数组中的重复项。
时间复杂度:
时间复杂度为O(n),只进行了一次数组的遍历。
代码实现:

class Solution {public int removeDuplicates(int[] nums) {if(nums.length < 2) return nums.length;int idx = 0;for(int i = 1;i < nums.length;i++){if(nums[i] != nums[idx]){idx = idx + 1;nums[idx] = nums[i];}}return idx + 1;}
}

27.移除元素

思路:
本题的思路和第26题一样,需要一个辅助下标idx,遍历整个数组,当遇到数组元素不等于val时,则将其加入到删除后的数组中,同时辅助下标后移,遍历结束后返回辅助下标idx的值即可,详细的视频讲解点击视频讲解-移除元素。
时间复杂度:
时间复杂度为O(n)n为数组的长度。
代码实现:

class Solution {public int removeElement(int[] nums, int val) {int idx = 0;for(int i = 0;i < nums.length;i++){if(nums[i] != val){nums[idx] = nums[i];idx = idx + 1;}}return idx;}
}

80.删除有序数组中的重复项 Ⅱ

思路:
本题采用双指针来求解,解法和26.删除有序数组中的重复项类似,但是由于本题中每个元素可以出现两次,所以将idx设置为1,设置前两个位置为结果数组,第二个指针从索引为2开始,比较当前元素和结果数组中的倒数第二个元素的值是否相等(即nums[idx - 1],注意这里不要使用nums[--idx],因为这样会改变idx的值,导致索引不正确),如果相等则i++,继续向后遍历,如果不相等则加入到结果数组中(这里可以这样做的原因是nums有序数组!!!如果是无序数组则不能这么做),下面是一个模拟的例子:
在这里插入图片描述
视频讲解点击视频讲解-删除有序数组中的重复项 Ⅱ
时间复杂度:
时间复杂度为O(n),其中n为数组的长度。
代码实现:

class Solution {public int removeDuplicates(int[] nums) {if(nums.length <= 2) return nums.length;int idx = 1;for(int i = 2;i < nums.length ; i++){if(nums[i] != nums[idx - 1]){nums[++idx] = nums[i];}}return idx + 1;}
}

2.相向双指针

双指针 一般是一个在开头,一个在结尾,两者相向处理问题,一般用来确定某个符合条件的子数组,需要维护左右边界。

2.1例题

11.盛最多水的容器

思路:
本题采用双指针来求解,由于盛水的体积为宽✖高,因此可以定义首尾两个指针,枚举出不同高度的体积并取最大值,在移动指针的过程中,应该移动高度较小的指针,因为盛水的高度是由短板来决的,如图,不同的颜色表示每次移动指针后得到的体积。视频讲解点击视频讲解-盛最多水的容器。
在这里插入图片描述

时间复杂度:
时间复杂度为O(n),空间复杂度O(1)
代码实现:

class Solution {public int maxArea(int[] height) {int ans = 0;int l = 0;int r =height.length - 1;while(l < r){ans = Math.max(ans,Math.min(height[l],height[r]) * (r-l));if(height[l] < height[r]) l++;else r--;}return ans;}
}

42.接雨水

思路:
本题采用双指针来求解,类似于11.盛水最多的容器,盛水的多少取决于左右柱子里较低的一个。通过维护左边和右边的最大高度,来计算整个数组中的装水容量,定义两个变量lmaxrmax,初始值都为0,用于记录当前位置左边和右边的最大高度,不断更新左右两边的最大高度来计算每个位置的水位,然后将各个位置的水位差累加起来得到总的装水容量,下面是一个模拟的例子:
在这里插入图片描述
视频讲解点击视频讲解-接雨水。
时间复杂度:
这段代码的时间复杂度是O(n),其中n是height数组的长度。由于只使用了一个while循环来遍历height,没有嵌套的循环,因此时间复杂度是线性的。
代码实现:

class Solution {public int trap(int[] height) {int l = 0;int r = height.length - 1;int lmax = 0;int rmax = 0;int ans = 0;while(l < r){lmax = Math.max(lmax,height[l]);rmax = Math.max(rmax,height[r]);if(lmax < rmax){ans += lmax - height[l];l++;} else{ans += rmax - height[r];r--;}}return ans;}
}

581.最短无序连续子数组

思路:
本题采用双指针解决,分别从数组的两端进行遍历,确定结果数组的左右边界。确定左边界的条件如果当前元素小于左边界处的最大值,则更新右边界,否则更新左边界的最大值(左边界的右边不应该出现比左边界小的值);确定右边界的条件是如果当前元素大于右边界处的最小值,则更新左边界,否则更新右边界的最小值(右边界的左边不应该出现比右边界大的值),得到左右边界后返回子数组的长度即可。
时间复杂度:
时间复杂度为O(n)n为数组长度。
代码实现:

class Solution {public int findUnsortedSubarray(int[] nums) {//初始化工作://start、end分别是从前向后和从后向前遍历数组的两个指针//需要注意的是end不是从len - 1开始,初始值应该为-1,这是为了处理数组本来就是有序数组的情况//lmax、rmin分别是遍历过程中维护的左边界的最大值和右边界的最小值int len = nums.length;int start = 0;int end = -1;int lmax = nums[0];int rmin = nums[len - 1]; for(int i = 0;i < len ; i++){//确定左边界if(nums[i] < lmax){end = i;} else {lmax = nums[i];}//确定右边界if(nums[len - i - 1] > rmin){start = len - i -1;} else {rmin = nums[len - i -1];}}return end - start + 1;}
}

参考资料:双指针-数组

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

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

相关文章

揭秘k-NN算法:简单技术背后的强大力量

近邻算法&#xff08;k-Nearest Neighbors, k-NN&#xff09;是一种基本且常用的分类与回归方法。它的主要特点是模型简单、易于理解&#xff0c;且在许多实际应用中表现良好。本文将详细介绍近邻算法的原理、实现步骤以及优缺点。 1. 原理简介 近邻算法基于一个核心思想&…

WebGL的医学培训软件开发

开发基于WebGL的医学培训软件是一项复杂且技术性强的任务&#xff0c;需要结合医学专业知识和计算机图形学技术。以下是详细的开发流程和关键步骤。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.需求分析与定义 目标用户&#xf…

二叉树——进阶(递归创建,非递归,广度优先,翻转,深度,对称)

二叉树——进阶 二叉树的递归创建非递归前中后序遍历非递归前序遍历非递归中序遍历非递归后序遍历 广度优先遍历二叉树&#xff08;层序遍历&#xff09;翻转二叉树 二叉树深度最大深度最小深度 对称二叉树 二叉树的递归创建 1&#xff0c;二叉树是一种结构相对固定的数据&…

【Rust日报】函数指针与闭包的区别

函数指针与闭包的区别 在 Rust 中&#xff0c;函数指针用于直接指向一个确定签名的函数&#xff0c;适用于不需要捕获外部环境的场景。相对闭包来说&#xff0c;函数指针语法简单&#xff0c;性能略高但不能保持状态。闭包则功能更强大&#xff0c;能够捕获和使用其定义时的环境…

vue3中element-plus下拉菜单与图标的使用

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 http://218.75.87.38:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a; h…

rust语言一些规则学习

目录 rust中迭代器的使用&#xff08;iter().map()与for循环的区别&#xff09;map()与for的描述区别总结 最后更新时间2024-05-24 rust中迭代器的使用&#xff08;iter().map()与for循环的区别&#xff09; map()与for的描述 rust源码中关于iter().map()函数的解释&#xff…

用Python一键生成PNG图片的PowerPoint幻灯片

在当今的商业环境中,PowerPoint演示是展示和传递信息的常用方式。然而,手动将大量图像插入到幻灯片中往往是一项乏味且耗时的工作。但是,通过Python编程,我们可以轻松自动化这个过程,节省时间和精力。 C:\pythoncode\new\folderTOppt.py 在本文中,我将介绍如何使用Python、wx…

【C++初阶】vector

✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅ ✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨ &#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1…

元组的定义和操作 学习!

元组的定义和操作 1&#xff09;元组的定义方式 &#xff08;元素, 元素, 元素, ... ) # 定义元组 t1 (2, "hi", True) t2 () t3 tuple() print(f"t1的类型是:{type(t1)}&#xff0c;内容是:{t1}") print(f"t2的类型是:{type(t2)}&#xff0c;内…

在winnas中使用docker desktop遇到的问题及解决方法记录

最近在尝试从群晖转向winnas&#xff0c;一些简单的服务依然计划使用docker来部署。群晖的docker简单易用且稳定&#xff0c;在win上使用docker desktop过程中遇到了不少问题&#xff0c;在此记录一下以供后来人参考。 一、安装docker desktop后启动时遇到无法启动docker引擎 …

【Unity AR开发插件】四、制作热更数据-AR图片识别场景

专栏 本专栏将介绍如何使用这个支持热更的AR开发插件&#xff0c;快速地开发AR应用。 链接&#xff1a; Unity开发AR系列 插件简介 通过热更技术实现动态地加载AR场景&#xff0c;简化了AR开发流程&#xff0c;让用户可更多地关注Unity场景内容的制作。 “EnvInstaller…”支…

C++11-共享指针shared_ptr使用注意事项

两种创建 shared_ptr 的方式 通过构造函数直接构造 shared_ptr: std::shared_ptr<MyClass> ptr(new MyClass(10));内存分配&#xff1a; 两次内存分配&#xff1a;一次为对象内存 (new MyClass(10))&#xff0c;一次为控制块内存。 灵活性&#xff1a; 允许自定义删除器&…

2024年电工杯数学建模竞赛A题完整解析 | 代码 论文分享

A 题 问题一1.1问题分析1.2第一问1.2.1指标定义1.2.2结果计算1.2.3关键因素分析 1.3第二问1.3.1模型建立1.3.2算法求解1.3.3求解结果 1.4第三问1.4.1模型建立1.4.2计算结果 第二题2.1 问题分析2.2第一问2.2.1指标计算 数据与代码代码分享完整资料 A题的问题一和问题二终于完成啦…

Spring Boot :从上传的二维码图片中读取信息

在现代应用中&#xff0c;读取二维码中的信息是一个常见的需求。本文将介绍如何在 Spring Boot 项目中实现从上传的二维码图片中读取包含的信息&#xff0c;包括引入 ZXing 依赖、实现读取二维码信息的方法、编写处理上传文件的控制器&#xff0c;并提供详细的代码示例。 1. 引…

vue 纵向滚动菜单, 点击滚动到选中菜单

1 背景 需要设计一个纵向滚动菜单&#xff0c;要求丝滑点&#xff0c;默认显示选中菜单 2 思路 给定一个容器&#xff0c;样式包含overflow:hidden&#xff0c;默认高宽足够显示一个菜单&#xff08;以下用图标代替菜单&#xff09;&#xff0c;鼠标悬浮时增大容器高度&#…

电能抄表是什么?

1.电能抄表的概念和功能 电能抄表&#xff0c;说白了&#xff0c;是一种用于数据记录载入电力工程使用量的机器。它主要职能精确测量做好记录客户在一定时间内的耗电量&#xff0c;为供电公司提供准确的收费根据。电能抄表的应用&#xff0c;不仅方便了电费的清算&#xff0c;…

NSSCTF | [SWPUCTF 2021 新生赛]no_wakeup

打开题目后&#xff0c;点击三个&#xff1f;&#xff0c;发现是一个php序列化脚本 <?phpheader("Content-type:text/html;charsetutf-8"); error_reporting(0); show_source("class.php");class HaHaHa{public $admin;public $passwd;public function…

Spring MVC的数据转换及数据格式化:java 转换器接口(将一种类型的对象转换为另一种类型及其子类对象)

文章目录 引言I 将String转为BaseEnum的子类对象1.1 注册转换器工厂1.2 实现转换器工厂1.3 实现转换器接口 `interface Converter<S, T> `1.4 根据枚举code和type获取枚举II 枚举2.1 枚举接口2.2 枚举子类2.3 请求实体引言 Spring MVC的数据转换及数据格式化 应用场景:…

结构体变量的创建和初始化以及内存对齐

前言 嗨&#xff0c;我是firdawn&#xff0c;在本章中我们将介绍&#xff0c;结构体变量的创建和初始化&#xff0c;结构成员访问操作符以及结构体的内存对齐&#xff0c;下面是本章的思维导图&#xff0c;接下来&#xff0c;让我们开始今天的学习吧&#xff01; 一&#xf…

电脑远程控制另一台电脑怎么弄?

可以远程控制另一台电脑吗&#xff1f; “你好&#xff0c;我对远程访问技术不太了解。现在&#xff0c;我希望我的朋友可以远程控制我的Windows 10电脑&#xff0c;以便她能帮我解决一些问题。请问&#xff0c;有没有免费的方法可以实现这种远程控制&#xff1f;我该如何操作…