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

使用双指针来解决此问题,关键词“有序”数组,一个 index 指针用于构建新数组,一个 i 指针用于遍历整个数组
以下是代码的中文解释以及算法思想:
算法思想
这道题要求对一个有序数组进行去重,使得每个元素最多出现两次。我们需要在原数组上进行操作,不能使用额外的空间。为了实现这个要求,我们可以使用双指针法来完成:
-
初始化两个指针:
index指针表示下一个可以插入的有效位置(用于构建结果数组),它初始值为 2,因为前两个元素无论如何都可以直接保留。i指针遍历整个数组,从第三个元素开始检查(因为我们允许每个元素最多出现两次,所以不需要检查前两个元素)。
-
条件检查:
- 对于每个元素
nums[i],我们检查它是否等于nums[index - 2]。如果不等,则表示nums[i]至少可以插入到当前构建的结果数组中。 - 如果
nums[i] != nums[index - 2],则将nums[i]放到nums[index]位置上,并将index指针向后移动一位,准备下一个位置。
- 对于每个元素
-
返回结果:
- 最终
index的值就是新数组的长度,因为index指针的值代表了有效数组的长度。 - 原数组前
index个元素就是去重后的数组,且每个元素最多出现两次。
- 最终
代码示例
public class Solution {public int removeDuplicates(int[] nums) {if (nums.length <= 2) return nums.length;int index = 2; // 从第三个元素开始检查for (int i = 2; i < nums.length; i++) {// 如果当前元素 nums[i] 不等于 nums[index - 2],说明该元素可以加入if (nums[i] != nums[index - 2]) {nums[index] = nums[i];index++;}}return index;}
}
具体解释
- 数组长度小于等于 2:如果数组长度不超过 2,直接返回数组长度,因为每个元素都可以出现两次。
- 遍历数组:
- 从第三个元素开始(
i = 2),逐个检查每个元素nums[i]。 - 如果当前元素
nums[i]不等于nums[index - 2],表示当前元素没有超过出现两次的限制。 - 将当前元素
nums[i]放到nums[index]位置上,然后将index向后移动一位。
- 从第三个元素开始(
- 返回结果:
index的值就是数组去重后的长度,数组的前index个元素就是符合要求的结果。
复杂度分析
- 时间复杂度:O(n),因为我们只遍历了一遍数组。
- 空间复杂度:O(1),因为我们在原数组上进行操作,没有使用额外的空间。
示例
假设输入数组为 {1, 1, 1, 2, 2, 3}:
- 初始状态:
index = 2 - 遍历:
i = 2,nums[i] = 1,nums[index - 2] = 1,相等,跳过此元素。i = 3,nums[i] = 2,nums[index - 2] = 1,不相等,将nums[i]赋值给nums[index],index增加 1。i = 4,nums[i] = 2,nums[index - 2] = 1,不相等,将nums[i]赋值给nums[index],index增加 1。i = 5,nums[i] = 3,nums[index - 2] = 2,不相等,将nums[i]赋值给nums[index],index增加 1。
- 最终结果:返回的长度
index = 5,即{1, 1, 2, 2, 3}
java 代码如下:
class Solution {public int removeDuplicates(int[] nums) {// if (nums.length <= 2) return nums.length;int index = 2;for(int i = 2; i < nums.length; ++i) {if(nums[i] != nums[index - 2]) { //注意是index - 2, 而不是 i - 2nums[index++] = nums[i];}}return index;}
}
为什么这行代码的判断条件不是nums[i] != nums[i - 2]
if (nums[i] != nums[index - 2]) {
这是一个很好的问题。之所以判断条件写成 nums[i] != nums[index - 2] 而不是 nums[i] != nums[i - 2],是因为我们希望使用 index 指针来追踪构建新数组的有效长度,并确保每个元素最多出现两次。下面是具体原因:
原因解释
-
index指针的作用:index指针代表的是新数组的当前位置,也就是我们构建的、符合条件的数组的长度。index - 2始终指向新数组的倒数第二个元素。因此,nums[index - 2]可以用来判断当前的nums[i]是否已经出现了两次。
-
避免原数组的重复元素影响判断:
- 如果直接用
nums[i - 2],它表示的是原数组的倒数第二个元素。然而,我们的目标是构建一个新的符合条件的数组,这个数组并不直接等同于原数组。 - 例如,在原数组中,某个元素可能已经出现多次,但在新数组(由
index控制)中它可能只出现了一次。因此,判断条件需要使用nums[index - 2]而不是nums[i - 2]。
- 如果直接用
-
控制新数组的内容:
- 通过
nums[index - 2],我们可以确保只有符合条件的元素才被添加到新数组中,避免出现超过两次的重复。 - 如果使用
nums[i - 2],则我们判断的是原数组中的元素而不是新构建的数组,可能会导致多次重复的元素被错误地加入。
- 通过
举例说明
假设输入数组为 {1, 1, 1, 2, 2, 3}:
-
初始时
index = 2,我们从第三个元素(i = 2)开始遍历。- 当
i = 2时,nums[i] = 1,如果我们使用nums[i - 2]进行判断,那就是nums[0] = 1。此时,它会与nums[i]相等,判断条件为false,意味着它会被加入到新数组中,导致1出现三次,这是不符合题意的。 - 而使用
nums[index - 2](即nums[0] = 1)作为判断条件时,我们可以正确地跳过这个元素,避免多余的重复。
- 当
通过使用 index 指针,我们有效地控制了新数组的内容,并保证每个元素最多出现两次。
相关文章:
Leetcode 删除有序数组中的重复项 Ⅱ
使用双指针来解决此问题,关键词“有序”数组,一个 index 指针用于构建新数组,一个 i 指针用于遍历整个数组 以下是代码的中文解释以及算法思想: 算法思想 这道题要求对一个有序数组进行去重,使得每个元素最多出现两…...
大模型学习笔记------什么是大模型
大模型学习笔记------什么是大模型 1、大模型定义2、大模型发展历程3、大模型的核心特点4、大模型的应用领域5、大模型面临的挑战6、结束语 近两年大模型超级火,并且相关产品迎来爆发式增长。在工作中,也常常接触到大模型,并且已经开始进行相…...
【unique_str 源码学习】
文章目录 1.删除器定义2. operator->() 运算符重载3. add_lvalue_reference<element_type>::type 使用 基本原理这篇博主写的很详细 https://yngzmiao.blog.csdn.net/article/details/105725663 1.删除器定义 deleter_…...
flask第一个应用
文章目录 安装一、编程第一步二、引入配置三、代码解析 安装 python环境安装的过程就不重复赘述了,flask安装使用命令pip install Flask即可,使用命令pip show Flask查看flask版本信息 提示:以下是本篇文章正文内容,下面案例可供…...
华为OD机试真题(Python/JS/C/C++)- 考点 - 细节
华为OD机试 2024E卷题库疯狂收录中,刷题 点这里。 本专栏收录于《华为OD机试真题(Python/JS/C/C)》。...
【C++刷题】力扣-#628-三个数的最大乘积
题目描述 给你一个整型数组 nums ,在数组中找出由三个数组成的最大乘积,并输出这个乘积。 示例 示例 1 输入:nums [1,2,3] 输出:6示例 2 输入:nums [1,2,3,4] 输出:24示例 3 输入:nums […...
Java项目实战II基于Java+Spring Boot+MySQL的工程教育认证的计算机课程管理平台(源码+数据库+文档)
目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者,专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 随着工程教…...
基于微信小程序实现信阳毛尖茶叶商城系统设计与实现
作者简介:Java领域优质创作者、CSDN博客专家 、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO特邀作者、多年架构师设计经验、多年校企合作经验,被多个学校常年聘为校外企业导师,指导学生毕业设计并参与学生毕业答辩指导,…...
设计一个灵活的RPC架构
RPC架构 RPC本质上就是一个远程调用,需要通过网络来传输数据。传输协议可以有多种选择,但考虑到可靠性,一般默认采用TCP协议。为了屏蔽网络传输的复杂性,需要封装一个单独的数据传输模块用来收发二进制数据,这个单独模…...
大数据计算里的Broadcast Hash Join/Shuffle Hash Join/Sort Merge Join
文章目录 Broadcast Hash Join场景 Shuffle Hash Join场景 Sort Merge Join场景 Broadcast Hash Join 场景 大表和小小表,直接把B表加载到内存,然后读块1内容和内存中数据匹配 Shuffle Hash Join 场景 大表和小表JOIN ,小表分块后能加载…...
Java - 手写识别; 如何用spring ai和大模型做手写识别教程
识别后的文字 利用大模型提升Java手写识别:更简单、更高效 在Java场景中,我们经常需要处理手写识别的问题。过去,这类需求主要依赖于OCR技术,但其效果并不总是稳定。随着大模型的发展,使用大模型进行java手写识别成为…...
【Linux】用户权限管理:创建受限用户并配置特定目录访问权限
本文详细介绍了如何在 Linux 系统中创建一个名为 agent 的新用户,并限制其在特定目录下的权限。通过使用 useradd 命令创建用户,并使用 usermod 命令将新用户添加到现有用户组中,确保其具有适当的权限。接着,通过 chown 和 chmod …...
pgsql表分区和表分片设计
在设计 PostgreSQL 表分区和表分片时,主要目标是提高查询性能、可扩展性和数据管理的效率。以下是一些关键的设计步骤和策略: 1. 分区策略 水平分片:选择按日期进行水平分片,每天一个分片。这种策略适用于具有时间序列数据的场景…...
灵动AI ——视频创作新引擎 开启视觉奇幻之旅
灵动AI视频官网地址:https://aigc.genceai.com/ 灵动AI 科技与艺术的完美融合之作。它代表着当下最前沿的影像技术,为我们带来前所未有的视觉盛宴。...
AI设计、作图、画画工具哪个好用?看完这篇你就知道怎么选了
Stable Diffusion Stable Diffusion 是由 Stability AI 推出的开源 AI 文本到图像生成模型,以其开放性和灵活性在 AI 视觉工具领域广受欢迎。与 DALL-E 或 Midjourney 等只能依赖云计算的工具不同,Stable Diffusion 支持本地运行,也广泛兼容多…...
【python ASR】win11-从0到1使用funasr实现本地离线音频转文本
文章目录 前言一、前提条件安装环境Python 安装安装依赖,使用工业预训练模型最后安装 - torch1. 安装前查看显卡支持的最高CUDA的版本,以便下载torch 对应的版本的安装包。torch 中的CUDA版本要低于显卡最高的CUDA版本。2. 前往网站下载[Pytorch](https://pytorch.o…...
myqld二进制安装和破解数据库密码(linux)
安装和基本配置 1.首先把下载下来的mysql安装包放到本地这里下载的是5.7版本为演示 1)解压 tar xf mysql-5.7.20-linux-glibc2.12-x86_64.tar.gz -C /usr/local -把安装包解压到/usr/local cd /usr/local …...
防重方案-订单防重方案笔记
订单防重设计 订单重复提交概念解决方案前端防重机制后端防重机制利用Token机制基于数据库的唯一索引 Token机制方案介绍 其他 订单重复提交概念 重复提交指,连点按钮进行重复提交操作,不包括刷新后的重新下单,重新下单已非同一订单的概念。…...
HTML、JavaScript和CSS实现注册页面设计
目录 一、实现要求 二、实现页面图 1、注册页面 2.用户ID、用户名、口令验证成功后显示页面 三、用户ID、用户名、口令、确定口令验证逻辑js代码 1、验证用户ID 2、验证用户名 3、验证口令密码 四、总结 五、代码仓库 一、实现要求 综合使用HTML、JavaScript和CSS进…...
Counter对象的使用样例
1. Counter类的定义和功能说明 Counter是一个用于跟踪值出现次数的有序集合。它可以接收一个可迭代对象作为参数,并生成一个字典,其中包含每个元素作为键,其计数作为值。 2. 统计列表或字符串中元素的出现次数 示例代码: from…...
终极AMD Ryzen调试指南:SMUDebugTool让你的处理器发挥最大潜力
终极AMD Ryzen调试指南:SMUDebugTool让你的处理器发挥最大潜力 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: ht…...
告别复制粘贴!手把手教你封装可复用的Echarts-for-weixin图表组件
微信小程序Echarts组件化实战:打造高复用图表解决方案 在数据驱动的产品设计中,图表可视化已成为微信小程序不可或缺的组成部分。面对多页面复用、动态数据更新等实际需求,直接使用原生ec-canvas组件往往会导致代码冗余和维护困难。本文将分享…...
Blender新手必看:别再乱点右上角那个“漏斗”了,详解大纲视图的4个隐藏开关
Blender新手避坑指南:揭秘大纲视图四大开关的实战应用 刚接触Blender时,界面右上角那个不起眼的漏斗图标就像潘多拉魔盒——点开后出现的四个神秘开关(禁用选中、视图隐藏、视图禁用、渲染禁用)让无数新手陷入选择困难。这些看似简…...
深入Linux内存管理:从虚拟内存到OOM Killer的完整解析
1. 从物理到虚拟:内存管理的演进与核心挑战干了这么多年系统开发和性能调优,内存问题始终是那个最让人头疼,但又不得不面对的“老朋友”。无论是半夜被报警叫醒处理线上服务的OOM(Out of Memory)崩溃,还是为…...
LangChain学习之提示词模板 Prompts(2/8)
模块 2: 提示词模板 (Prompts) 2.1 提示词 (Prompts) 概述 在与大型语言模型(LLM)交互时,提示词 (Prompt) 是向模型发出的指令或问题。一个好的提示词能够引导模型生成高质量、符合预期的输出。LangChain 提供了强大的提示词管理功能&#…...
Gemini 3.5 Flash:AI界“闪电侠”来袭,速度与性价比双封神!
极速、低成本、原生多模态、面向智能体(Agent) 的主力模型,代号 “雪兔”,当前面向公众免费开放。(图源网络,侵删)如果AI模型有“速度奥运会”,2026 年 5 月谷歌 I/O 大会上新发的 Gemini 3.5 Flash&#x…...
CSS锚点定位(Anchor Positioning)完全指南:实现精准定位
引言 CSS锚点定位(Anchor Positioning)是CSS定位领域的重大突破,它允许元素相对于其他元素进行定位,而不仅仅是相对于视口或父容器。这为实现复杂的UI组件如弹出菜单、工具提示、下拉选择器等提供了原生支持。 一、锚点定位核心概念 1.1 什么是锚点定位 …...
CANN/asc-devkit SIMT数学函数erfinvf
erfinvf 【免费下载链接】asc-devkit 本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。 项目地址: https://gitcode.com/ca…...
磁性衬底导向的宽带超材料吸波体的吸波机理及设计方案【附代码】
✨ 长期致力于磁性材料、超材料吸波体、宽频带微波吸收、吸波机理、智能算法研究工作,擅长数据搜集与处理、建模仿真、程序编写、仿真设计。 ✅ 专业定制毕设、代码 ✅ 如需沟通交流,点击《获取方式》 (1)对称模型分析多层反射干涉…...
3分钟搞定音乐格式转换:你的私人音乐解锁神器使用全攻略
3分钟搞定音乐格式转换:你的私人音乐解锁神器使用全攻略 【免费下载链接】unlock-music 在浏览器中解锁加密的音乐文件。原仓库: 1. https://github.com/unlock-music/unlock-music ;2. https://git.unlock-music.dev/um/web 项目地址: htt…...
