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

leetcode26:删除有序数组中的重复项Ⅰ(快慢指针解法)

文章目录

  • 一、 题目描述
  • 二、 核心思路:快慢指针
  • 三、 代码实现与深度解析
  • 四、 关键点与复杂度分析
  • 五、 总结与拓展

leetcode26. 删除有序数组中的重复项,【难度:简单;通过率:58.2%】,这道题是双指针之 快慢指针模式的经典入门,它要求我们在一个 有序数组原地删除重复项,使每个元素只出现 一次

一、 题目描述

给你一个升序排列的数组 nums,请你原地删除重复出现的元素,使得每个元素只出现一次,返回删除后数组的新长度。元素的相对顺序应该保持一致

更规范地说,如果在删除重复项之后有 k 个元素,那么 nums 的前 k 个元素应该保存最终结果

示例:

示例 1:

输入:nums = [1,1,2]
输出:2, nums = [1,2,_]
解释:函数应该返回新长度 k = 2, 并且原数组的前两个元素被修改为 1, 2

示例 2:

输入:nums = [0,0,1,1,1,2,2,3,3,4]
输出:5, nums = [0,1,2,3,4,_,_,_,_,_]
解释:函数应该返回新长度 k = 5, 并且原数组的前五个元素被修改为 0, 1, 2, 3, 4

二、 核心思路:快慢指针

解决此类在有序数组上进行原地修改的问题,快慢指针是最高效且最常用的方法

我们将数组逻辑上分为两部分:

  • [0...slow-1]:这是我们已经处理好的、去重后的新数组
  • [slow...fast-1]:这是 fast 指针已经扫描过,但包含重复项的区域(由于是“原地操作”,这些元素将被覆盖
  • [fast...n-1]:这是待 fast 指针探索的未知区域

指针职责:

  • fast (快指针):作为“读取”指针,它负责遍历整个原始数组,寻找可以保留的元素
  • slow (慢指针):作为“写入”指针,它指向新数组的下一个空闲位置,等待接收下一个唯一的元素。同时,slow 的值也代表了新数组的当前长度

三、 代码实现与深度解析

参考代码

class Solution {public int removeDuplicates(int[] nums) {// 边界条件处理:如果数组为空或只有一个元素,无需去重,直接返回其长度// 题目约束 nums.length >= 1,所以这里只考虑 nums.length == 1 的情况// 如果数组长度为0,按题目约束不会出现,但如果考虑,则应返回0if (nums.length == 0) { // 额外添加的空数组判断,更严谨return 0;}// 初始化快慢指针// slow 指针:指向下一个要写入的唯一元素的位置// 数组的第一个元素 nums[0] 总是唯一的,所以新数组的有效长度至少为 1// slow 从 1 开始,意味着 nums[0] 已经被保留int slow = 1; // fast 指针:从数组的第二个元素开始遍历 (索引 1)// 它的任务是探索数组中的每一个元素for (int fast = 1; fast < nums.length; fast++) {// 核心判断:如果 fast 指向的元素与它前一个元素不同// 这说明 nums[fast] 是一个新的、唯一的元素if (nums[fast] != nums[fast - 1]) {// 将唯一的元素复制到 slow 指针的位置nums[slow] = nums[fast];// slow 指针前进一格,为下一个唯一元素腾出位置slow++;}// 如果 nums[fast] 与 nums[fast - 1] 相同,说明是重复元素,// 此时 slow 不动,fast 继续前进,相当于“跳过”了这个重复元素}// 循环结束后,slow 的值就是去重后数组的新长度 kreturn slow;}
}

提交结果:

在这里插入图片描述


四、 关键点与复杂度分析

  • 原地修改:该算法不使用任何额外的数组空间,直接在输入数组上进行修改,满足 O(1) 额外空间复杂度的要求
  • 数组有序性:算法的核心依赖于输入数组是有序的。这使得我们只需比较相邻元素即可判断重复
  • 相对顺序保持:由于 fast 指针是顺序遍历的,并且只有唯一的元素才会被复制到 slow 的位置,因此去重后的元素相对顺序得到了保持
  • 时间复杂度O(N) 快指针 fast 遍历了整个数组一次,每个元素最多被访问一次
  • 空间复杂度O(1) 只使用了常数个额外变量(slow, fast),没有使用与输入规模相关的额外空间

五、 总结与拓展

本题是快慢指针模式的经典入门题,本质上就是双指针法,为每个指针(引用)赋予不同的身份和作用,实现一种快慢遍历、填充的效果

拓展思考:

这道题是 LeetCode 80 (删除有序数组中的重复项 II) 的前置题。如果题目要求你“每个元素最多出现两次”,该如何修改你的快慢指针逻辑呢?

参考博客:

LeetCode 80 快慢指针法详解,以及基于LC 26、LC 80总结出的此类题通用模板

http://www.xdnf.cn/news/1353691.html

相关文章:

  • X射线胸部肺炎检测:基于深度学习的医学影像分析项目
  • 概率论基础教程第六章 随机变量的联合分布(二)
  • 告别SaaS数据绑架,拥抱数据主权:XK+独立部署版跨境商城定制,为海外物流企业深度赋能
  • 遥感机器学习入门实战教程|Sklearn案例⑨:数据预处理(Processing)
  • 不用 if-else,Spring Boot 怎么知道 ?status=10 是哪个枚举?
  • 小白成长之路-k8s原理(一)
  • STM32学习笔记19-FLASH
  • [Mysql数据库] 选择备份策略选择题
  • 工业场景烟雾识别误报率↓82%!陌讯多模态融合算法实战解析
  • 水泉村信息化服务小程序的设计与实验
  • 54 C++ 现代C++编程艺术3-移动构造函数
  • 用 Go + GitHub Models API 打造一个免费的 ChatBot
  • 全面解析JVM预热:原理、价值与实践指南
  • MYSQL-约束
  • 【数据结构】线性表——链表
  • 微服务的编程测评系统15-头像上传-OSS
  • 高阶数据结构---ST表
  • kafaka知识要点
  • VLOOKUP专题训练
  • UE C++ 堆化
  • windows中bat脚本的一些操作(三)
  • 算法第五十五天:图论part05(第十一章)
  • 图论与最短路学习笔记
  • 【数据结构】跳表的概率模型详解与其 C 代码实现
  • 深度学习开篇
  • `strlen` 字符串长度函数
  • python 字典有序性的实现和OrderedDict
  • 计算机网络 各版本TLS握手的详细过程
  • 电脑零广告快响应提速(一)之卸载搜狗输入法使用RIME—东方仙盟
  • python re模块常用方法