当前位置: 首页 > news >正文

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

在这里插入图片描述

使用双指针来解决此问题,关键词“有序”数组,一个 index 指针用于构建新数组,一个 i 指针用于遍历整个数组

以下是代码的中文解释以及算法思想:

算法思想

这道题要求对一个有序数组进行去重,使得每个元素最多出现两次。我们需要在原数组上进行操作,不能使用额外的空间。为了实现这个要求,我们可以使用双指针法来完成:

  1. 初始化两个指针

    • index 指针表示下一个可以插入的有效位置(用于构建结果数组),它初始值为 2,因为前两个元素无论如何都可以直接保留。
    • i 指针遍历整个数组,从第三个元素开始检查(因为我们允许每个元素最多出现两次,所以不需要检查前两个元素)。
  2. 条件检查

    • 对于每个元素 nums[i],我们检查它是否等于 nums[index - 2]。如果不等,则表示 nums[i] 至少可以插入到当前构建的结果数组中。
    • 如果 nums[i] != nums[index - 2],则将 nums[i] 放到 nums[index] 位置上,并将 index 指针向后移动一位,准备下一个位置。
  3. 返回结果

    • 最终 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 = 2nums[i] = 1nums[index - 2] = 1,相等,跳过此元素。
    • i = 3nums[i] = 2nums[index - 2] = 1,不相等,将 nums[i] 赋值给 nums[index]index 增加 1。
    • i = 4nums[i] = 2nums[index - 2] = 1,不相等,将 nums[i] 赋值给 nums[index]index 增加 1。
    • i = 5nums[i] = 3nums[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 指针来追踪构建新数组的有效长度,并确保每个元素最多出现两次。下面是具体原因:

原因解释

  1. index 指针的作用

    • index 指针代表的是新数组的当前位置,也就是我们构建的、符合条件的数组的长度。
    • index - 2 始终指向新数组的倒数第二个元素。因此,nums[index - 2] 可以用来判断当前的 nums[i] 是否已经出现了两次。
  2. 避免原数组的重复元素影响判断

    • 如果直接用 nums[i - 2],它表示的是原数组的倒数第二个元素。然而,我们的目标是构建一个新的符合条件的数组,这个数组并不直接等同于原数组。
    • 例如,在原数组中,某个元素可能已经出现多次,但在新数组(由 index 控制)中它可能只出现了一次。因此,判断条件需要使用 nums[index - 2] 而不是 nums[i - 2]
  3. 控制新数组的内容

    • 通过 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 删除有序数组中的重复项 Ⅱ

使用双指针来解决此问题&#xff0c;关键词“有序”数组&#xff0c;一个 index 指针用于构建新数组&#xff0c;一个 i 指针用于遍历整个数组 以下是代码的中文解释以及算法思想&#xff1a; 算法思想 这道题要求对一个有序数组进行去重&#xff0c;使得每个元素最多出现两…...

大模型学习笔记------什么是大模型

大模型学习笔记------什么是大模型 1、大模型定义2、大模型发展历程3、大模型的核心特点4、大模型的应用领域5、大模型面临的挑战6、结束语 近两年大模型超级火&#xff0c;并且相关产品迎来爆发式增长。在工作中&#xff0c;也常常接触到大模型&#xff0c;并且已经开始进行相…...

【unique_str 源码学习】

文章目录 &#xff11;&#xff0e;删除器定义2. operator->() 运算符重载3. add_lvalue_reference<element_type>::type 使用 基本原理这篇博主写的很详细 https://yngzmiao.blog.csdn.net/article/details/105725663 &#xff11;&#xff0e;删除器定义 deleter_…...

flask第一个应用

文章目录 安装一、编程第一步二、引入配置三、代码解析 安装 python环境安装的过程就不重复赘述了&#xff0c;flask安装使用命令pip install Flask即可&#xff0c;使用命令pip show Flask查看flask版本信息 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供…...

华为OD机试真题(Python/JS/C/C++)- 考点 - 细节

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题 点这里。 本专栏收录于《华为OD机试真题&#xff08;Python/JS/C/C&#xff09;》。...

【C++刷题】力扣-#628-三个数的最大乘积

题目描述 给你一个整型数组 nums &#xff0c;在数组中找出由三个数组成的最大乘积&#xff0c;并输出这个乘积。 示例 示例 1 输入&#xff1a;nums [1,2,3] 输出&#xff1a;6示例 2 输入&#xff1a;nums [1,2,3,4] 输出&#xff1a;24示例 3 输入&#xff1a;nums […...

Java项目实战II基于Java+Spring Boot+MySQL的工程教育认证的计算机课程管理平台(源码+数据库+文档)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 随着工程教…...

基于微信小程序实现信阳毛尖茶叶商城系统设计与实现

作者简介&#xff1a;Java领域优质创作者、CSDN博客专家 、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO特邀作者、多年架构师设计经验、多年校企合作经验&#xff0c;被多个学校常年聘为校外企业导师&#xff0c;指导学生毕业设计并参与学生毕业答辩指导&#xff0c;…...

设计一个灵活的RPC架构

RPC架构 RPC本质上就是一个远程调用&#xff0c;需要通过网络来传输数据。传输协议可以有多种选择&#xff0c;但考虑到可靠性&#xff0c;一般默认采用TCP协议。为了屏蔽网络传输的复杂性&#xff0c;需要封装一个单独的数据传输模块用来收发二进制数据&#xff0c;这个单独模…...

大数据计算里的Broadcast Hash Join/Shuffle Hash Join/Sort Merge Join

文章目录 Broadcast Hash Join场景 Shuffle Hash Join场景 Sort Merge Join场景 Broadcast Hash Join 场景 大表和小小表&#xff0c;直接把B表加载到内存&#xff0c;然后读块1内容和内存中数据匹配 Shuffle Hash Join 场景 大表和小表JOIN &#xff0c;小表分块后能加载…...

Java - 手写识别; 如何用spring ai和大模型做手写识别教程

识别后的文字 利用大模型提升Java手写识别&#xff1a;更简单、更高效 在Java场景中&#xff0c;我们经常需要处理手写识别的问题。过去&#xff0c;这类需求主要依赖于OCR技术&#xff0c;但其效果并不总是稳定。随着大模型的发展&#xff0c;使用大模型进行java手写识别成为…...

【Linux】用户权限管理:创建受限用户并配置特定目录访问权限

本文详细介绍了如何在 Linux 系统中创建一个名为 agent 的新用户&#xff0c;并限制其在特定目录下的权限。通过使用 useradd 命令创建用户&#xff0c;并使用 usermod 命令将新用户添加到现有用户组中&#xff0c;确保其具有适当的权限。接着&#xff0c;通过 chown 和 chmod …...

pgsql表分区和表分片设计

在设计 PostgreSQL 表分区和表分片时&#xff0c;主要目标是提高查询性能、可扩展性和数据管理的效率。以下是一些关键的设计步骤和策略&#xff1a; 1. 分区策略 水平分片&#xff1a;选择按日期进行水平分片&#xff0c;每天一个分片。这种策略适用于具有时间序列数据的场景…...

灵动AI ——视频创作新引擎 开启视觉奇幻之旅

灵动AI视频官网地址&#xff1a;https://aigc.genceai.com/ 灵动AI 科技与艺术的完美融合之作。它代表着当下最前沿的影像技术&#xff0c;为我们带来前所未有的视觉盛宴。...

AI设计、作图、画画工具哪个好用?看完这篇你就知道怎么选了

Stable Diffusion Stable Diffusion 是由 Stability AI 推出的开源 AI 文本到图像生成模型&#xff0c;以其开放性和灵活性在 AI 视觉工具领域广受欢迎。与 DALL-E 或 Midjourney 等只能依赖云计算的工具不同&#xff0c;Stable Diffusion 支持本地运行&#xff0c;也广泛兼容多…...

【python ASR】win11-从0到1使用funasr实现本地离线音频转文本

文章目录 前言一、前提条件安装环境Python 安装安装依赖,使用工业预训练模型最后安装 - torch1. 安装前查看显卡支持的最高CUDA的版本&#xff0c;以便下载torch 对应的版本的安装包。torch 中的CUDA版本要低于显卡最高的CUDA版本。2. 前往网站下载[Pytorch](https://pytorch.o…...

myqld二进制安装和破解数据库密码(linux)

安装和基本配置 1.首先把下载下来的mysql安装包放到本地这里下载的是5.7版本为演示 1&#xff09;解压 tar xf mysql-5.7.20-linux-glibc2.12-x86_64.tar.gz -C /usr/local -把安装包解压到/usr/local cd /usr/local …...

防重方案-订单防重方案笔记

订单防重设计 订单重复提交概念解决方案前端防重机制后端防重机制利用Token机制基于数据库的唯一索引 Token机制方案介绍 其他 订单重复提交概念 重复提交指&#xff0c;连点按钮进行重复提交操作&#xff0c;不包括刷新后的重新下单&#xff0c;重新下单已非同一订单的概念。…...

HTML、JavaScript和CSS实现注册页面设计

目录 一、实现要求 二、实现页面图 1、注册页面 2.用户ID、用户名、口令验证成功后显示页面 三、用户ID、用户名、口令、确定口令验证逻辑js代码 1、验证用户ID 2、验证用户名 3、验证口令密码 四、总结 五、代码仓库 一、实现要求 综合使用HTML、JavaScript和CSS进…...

Counter对象的使用样例

1. Counter类的定义和功能说明 Counter是一个用于跟踪值出现次数的有序集合。它可以接收一个可迭代对象作为参数&#xff0c;并生成一个字典&#xff0c;其中包含每个元素作为键&#xff0c;其计数作为值。 2. 统计列表或字符串中元素的出现次数 示例代码&#xff1a; from…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

线程与协程

1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指&#xff1a;像函数调用/返回一样轻量地完成任务切换。 举例说明&#xff1a; 当你在程序中写一个函数调用&#xff1a; funcA() 然后 funcA 执行完后返回&…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

Mysql中select查询语句的执行过程

目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析&#xff08;Parser&#xff09; 2.4、执行sql 1. 预处理&#xff08;Preprocessor&#xff09; 2. 查询优化器&#xff08;Optimizer&#xff09; 3. 执行器…...

Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)

引言 工欲善其事&#xff0c;必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后&#xff0c;我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集&#xff0c;就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...

Golang——7、包与接口详解

包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...

从面试角度回答Android中ContentProvider启动原理

Android中ContentProvider原理的面试角度解析&#xff0c;分为​​已启动​​和​​未启动​​两种场景&#xff1a; 一、ContentProvider已启动的情况 1. ​​核心流程​​ ​​触发条件​​&#xff1a;当其他组件&#xff08;如Activity、Service&#xff09;通过ContentR…...

深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏

一、引言 在深度学习中&#xff0c;我们训练出的神经网络往往非常庞大&#xff08;比如像 ResNet、YOLOv8、Vision Transformer&#xff09;&#xff0c;虽然精度很高&#xff0c;但“太重”了&#xff0c;运行起来很慢&#xff0c;占用内存大&#xff0c;不适合部署到手机、摄…...

论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving

地址&#xff1a;LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂&#xff0c;正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...

git: early EOF

macOS报错&#xff1a; Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/.git/ remote: Enumerating objects: 2691797, done. remote: Counting objects: 100% (1760/1760), done. remote: Compressing objects: 100% (636/636…...