LeetCode.26,27,88三题-双指针的运用
本文将对3道解决方法类似的题目进行逐一分析,这三道题目分别是:
LeetCode.26 删除有序数组中的重复项
LeetCode.27 移除元素
LeetCode.88 合并两个有序数组
1. LeetCode.27 移除元素:
题目内容如下:

假设一个数组为:
nums = [0,1,2,2,3,0,4,2]
元素.
按照题目的要求,需要移除数组中所有等于
的元素。对于此题的解析,文章提供三种参考思路
1.在之前处理顺序表中删除元素的问题时,采用的方法是将目标元素后面的元素全部向前覆盖一位。但是,这种处理方法的时间复杂度为过于缓慢。
2.创建一个指针和一个新的数组,遍历整个数组,在便利的过程中。若被遍历的元素大小不等于时,将此元素复制到新开辟的数组中。当被遍历的元素大小等于
时,不复制并且将指针指向下一个元素。此方法的时间复杂度为
,相对于方法1,大幅度降低了程序执行所用的时间。但是,该方法因为新创建了一个数组。空间复杂度为
,不符合题目中的要求。
3. 虽然方法不满足题目的要求,但是可以通过方法
的思路来延伸出方法
,也就是文章题目中提到的双指针法。
对于本题,双指针法的具体用法如下:
1.创建两个指针,这里创建的指针分别命名为。最开始,两个指针都指向数组首元素的下标,即:

对于本题中创建的两个指针的动作,总结下来就是:将数组中位置上不等于
的元素放置到
中。
当两个指针所对应的元素相等且不等于时,都指向下一个元素。
当指针对应的值等于
时,指针
指向下一个位置,
不移动
当两个指针对应的元素不同且不等于时,将指针
对应的元素赋值到
位置。并且都向前移动一位。
用图片表示下列过程,即:
1.

2.

此时, 指针对应的值等于
。所以指针
不动,指针
继续向后移动:

此时,指针 对应的值不等于
,并且不等于
。所以,进行赋值操作:

再次向后移动,还会重复上面的动作:

当 遍历整个数组后,数组中内容如下图所示:

上述过程对应的代码为:
int removeElement(int* nums, int numsSize, int val){int dst = 0;int src = 0;while( src < numsSize){if( nums[src] != val){nums[dst++] = nums[src++];}else{src++;}}return dst;}
2. LeetCode.88 合并两个有序数组:
题目如下:

给出的示例如下:
用图片表示上面给出的示例,即:

对于这道题的解法,依旧采用双指针的思想,对于每一个数组均创建一个指针。但是,如果再次采用上面从头到尾进行遍历的方法,如果再某处需要插入元素,则还是会出现顺序表中插入元素出现的问题,即:每插入一个元素,都需要将后面的元素整体后移动一位。所以对于此题。最好采用从后向前,从大到小的顺序进行遍历。并且,将第一个数组中最大的元素与第二个数组中的元素分别进行比较。较大的则插入到第一个数组中后面的区域,将上述过程用图片演示,即:

上面的情况中,是第二个数组元素全部遍历完成时,第一个数组中的元素没有完成遍历。但是对于下面的情况,即:第一个数组完成遍历时,第二个数组并没有完成遍历:

用图片表示上述数组中元素的变化情况:


最后的结果如上图所示: 第二个数组中的元素并没有插入到第一个数组中。并且第一个数组已经遍历完成。而第二个数组没有遍历完成。
总结上述过程,为了方便陈述,将第一个数组命名为,将第二个数组命名为
。
为创建的指针命名为
,为
创建的指针命名为
。
从后向前对两个数组同时遍历,
当满足对应的元素>
对应的元素时,将
对应的元素在
中进行一个尾插操作。并且两个指针均指向前一个元素。
当不满足上述关系时,将对应的元素在
在前面插入元素的基础上进行一个尾插操作。并将
指向前一个元素。
当遍历完成时。标志着程序运行完成。当
遍历完成但是
没有完成遍历时。将
剩余的元素在
中进行插入。
用代码表示上述过程:
首先,题目中已给的参数分别是:

m表示 中非
的元素。n表示
中的元素。为了方便表示,用
表示上面的参数。
表示
中加上0元素的总长度。
代码如下:
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){int end1 = m - 1; int end2 = n -1;int end = m + n -1;while( end1 >= 0 && end2 >= 0){if( nums1[end1] > nums2[end2]){nums1[end--] = nums1[end1--];}else{nums1[end--] = nums2[end2--];}}while( end2 >= 0){nums1[end--] = nums2[end2--];}}
3. LeetCode. 26 删除有序数组中的重复项:
题目如下:

示例如下:

依旧采用双指针的方法来结局问题。创建两个指针分别为,
从上面的题目要求可知。题目涉及到对于数组中元素的更改。所以,创建的两个指针在开头可以处于相同位置,也可以处于不同位置。为了方便演示,这里给出不同位置的情况,例如下面图片所示的数组:

因为要保证数组中元素不能重复,所以,需要将后面的元素覆盖到前面元素的位置。所以,需要一个指针取读取后一位的元素,并且与前一位的元素进行对比。此时如果后一位元素与本位元素相同。则指向后一个元素:

此时,两个指针指向的元素不同,所以,先让指向后一位元素,再将
中的元素赋值给此时的
,再
,此时两个指针指向的元素相同,所以一直
,直到:

重复上面所说的步骤,即:

按照前面说的规则,最后的效果为
通过图片不难发现,程序结束的标志就是当指针 数组中元素个数
时(或者
数组中元素个数时)。
总结上述过程,可以分为三个要点:
1. 数组中元素个数时,程序结束
2.指向的值=
时,
指向后面的元素。
不变。
3. 指向的值不等于
时,先将
,再将
指向的值赋值到
,最后
+1.
用代码表示,即:
int removeDuplicates(int* nums, int numsSize){int dst = 0;int src = 1;while( src < numsSize){if( nums[src] == nums[dst]){src++;}else{dst++;nums[dst] = nums[src];src++;}}return dst+1;}
相关文章:
LeetCode.26,27,88三题-双指针的运用
本文将对3道解决方法类似的题目进行逐一分析,这三道题目分别是: LeetCode.26 删除有序数组中的重复项 LeetCode.27 移除元素 LeetCode.88 合并两个有序数组 1. LeetCode.27 移除元素: 题目内容如下: 假设一个数组为࿱…...
【Django】招聘面试管理01 创建项目运行项目
文章目录 前言一、创建项目二、运行项目三、访问后台管理页面四、配置项总结 前言 跟着视频学一学,记录一下。 一、创建项目 照着步骤创建虚拟环境,安装Django等依赖包,创建项目:【Django学习】01 项目创建、结构及命令 > d…...
C# 数据类型
C# 数据类型 一、整数类型(Integral Types)1.sbyte2.byte3.short4.ushort5.int6.uint7.long8.ulong 二、浮点数类型(Floating-Point Types)1.float2.double3.decimal 三、字符类型(Character Type)1.char 四…...
竞赛项目 深度学习手势识别算法实现 - opencv python
文章目录 1 前言2 项目背景3 任务描述4 环境搭配5 项目实现5.1 准备数据5.2 构建网络5.3 开始训练5.4 模型评估 6 识别效果7 最后 1 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 深度学习手势识别算法实现 - opencv python 该项目较为新颖…...
前端进阶html+css04----盒子模型
1.一个盒子由content(文本内容),padding,border,margin组成。 2.盒子的大小指的是盒子的宽度和高度。一般由box-sizing属性来控制。 1)默认情况下, 也就是box-sizing: content-box时,盒子的宽高计算公式如下: 盒子宽…...
Go Web--Go Module
目录 一、Go Module 1、开启Go Module 2、Go Module基本操作 3、使用GoLand创建Go Module项目 4、GoLand配置File Watchers 一、Go Module Go Module包管理工具----相当于Maven 1.11版本引入 1.12版本正式支持 告别GOPATH,使用Go Module管理项目,…...
Spring Boot 统一功能处理(拦截器实现用户登录权限的统一校验、统一异常返回、统一数据格式返回)
目录 1. 用户登录权限校验 1.1 最初用户登录权限效验 1.2 Spring AOP 用户统⼀登录验证 1.3 Spring 拦截器 (1)创建自定义拦截器 (2)将自定义拦截器添加到系统配置中,并设置拦截的规则 1.4 练习:登录…...
P4058 [Code+#1] 木材
1:思路:二分月数,然后贪心,就是说要求最小月数,拿每次判断是否到达s长度的时候我们就从大的开始拿。 int l-1,r1e181;while(l1<r){int midlr>>1;if(check(mid))rmid;else lmid;} 2:记得看数据&a…...
Python学习笔记第五十二天(Pandas 安装)
Python学习笔记第五十二天 Pandas 安装查看安装版本 安装验证结束语 Pandas 安装 安装 pandas 需要基础环境是 Python,开始前我们假定你已经安装了 Python 和 Pip。 使用 pip 安装 pandas: pip install pandas安装成功后,我们就可以导入 pandas 包使用…...
分布式搜索ElasticSearch-ES(一)
一、ElasticSearch介绍 ES是一款非常强大的开源搜索引擎,可以帮我们从海量的数据中快速找到我们需要的内容。 ElasticSearch结合kibana、Logstash、Beats,也就是elastic stack(ELK),被广泛运用在日志数据分析,实时监控等领域。 …...
react学习笔记——3. jsx语法规则
jsx是什么? jsx全称:javaScript XML是react定义的一种类似于XML的js扩展语法,是jsxml。 xml早期用于存储和传输数据,是标签加数据的形式。只不过后来慢慢的变成了json 其本质就是React.createElement(标签,属性,内容)方法的语法糖…...
MySQL分表实现上百万上千万记录分布存储的批量查询设计模式
我们知道可以将一个海量记录的 MySQL 大表根据主键、时间字段,条件字段等分成若干个表甚至保存在若干服务器中。唯一的问题就是跨服务器批量查询麻烦,只能通过应用程序来解决。谈谈在Java中的解决思路。其他语言原理类似。这里说的分表不是 MySQL 5.1 的…...
射频入门知识-1
信号源 示波器 综合测试仪 功率计 噪声测试仪 频谱分析仪 频谱分析仪: 放大器的噪声系数测试 放大器增益测试 噪声和增益是放大器的最关键指标,学学怎么用频谱仪做放大器的噪声测试 那个 hbf740 输入和输出阻抗匹配具体怎么搞 《ADS2011射频电路设计与…...
基于注解函数式编程实现组件解耦设计
随着业务系统的不断发展,系统架构变得越来越复杂,多种业务交叉写在一起,不仅带来了维护层面的困难,而且新人也很难以入手修改代码,业界通常采用组件模块化开发模式,用于降低系统的复杂度,本文主要针对组件化具体实施过程中,组件层面的方法解耦进行了详细讲解。 1前言 …...
并查集、树状数组
并查集、树状数组、线段树 并查集树状数组树状数组1 (单点修改,区间查询)树状数组2 (单点查询,区间修改) 并查集 【模板】并查集 题目描述 如题,现在有一个并查集,你需要完成合并和查询操作。 输入格式 第一行包含两个整数 …...
ES6中Null判断运算符(??)正确打开方式-
读取对象属性的时候,如果某个属性的值是null或者undefined,有时候需要为它们指定默认值。常见的作法是通过||运算符指定默认值。 const headerText response.settings.headerText || Hello, world!; const animationDuration response.settings.anima…...
java的内存模型
Java内存基础 并发编程模型的两个关键问题 线程之间如何通信及线程之间如何同步 线程之间的通信机制有两种:共享内存和消息传递。 在共享内存的并发模型里,线程之间共享程序的公共状态,通过写-读内存中的公共状态 进行隐式通信。在消息传…...
基于 CentOS 7 构建 LVS-DR 群集 配置nginx负载均衡
环境配置: RHCE客户机192.168.100.146node1lvs192.168.100.145node2RS192.168.100.147node3RS192.168.100.148 配置ipvsadm httpd: [rootnode1 ~]# yum install ipvsadm.x86_64 [rootnode2 ~]# yum install http -y [rootnode2 ~]# systemctl …...
CSS练习
CSS练习 工具代码运行结果 工具 HBuilder X 代码 <!DOCTYPE html> <!-- 做一个表格,6行4列实现隔行换色(背景色)并且第3列文字红色第一个单元格文字大小30px。最后一个单元格文字加粗--> <html><head><meta ch…...
基于深度学习的3D城市模型增强【Mask R-CNN】
在这篇文章中,我们描述了一个为阿姆斯特丹 3D 城市模型自动添加门窗的系统(可以在这里访问)。 计算机视觉用于从城市全景图像中提取有关门窗位置的信息。 由于这种类型的街道级图像广泛可用,因此该方法可用于较大的地理区域。 推荐…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
免费PDF转图片工具
免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...
C/C++ 中附加包含目录、附加库目录与附加依赖项详解
在 C/C 编程的编译和链接过程中,附加包含目录、附加库目录和附加依赖项是三个至关重要的设置,它们相互配合,确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中,这些概念容易让人混淆,但深入理解它们的作用和联…...
08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险
C#入门系列【类的基本概念】:开启编程世界的奇妙冒险 嘿,各位编程小白探险家!欢迎来到 C# 的奇幻大陆!今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类!别害怕,跟着我,保准让你轻松搞…...
淘宝扭蛋机小程序系统开发:打造互动性强的购物平台
淘宝扭蛋机小程序系统的开发,旨在打造一个互动性强的购物平台,让用户在购物的同时,能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机,实现旋转、抽拉等动作,增…...
