第11天 删除有序数组中的重复项 II

题意: 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。 不要使用额外的数组空间,你必须在原地修改输入数组 并在使用 O(1) 额外空间的条件下完成。

题目链接:https://leetcode.cn/problems/remove-duplicates-from-sorted-array-ii/

视频链接:https://www.bilibili.com/video/BV18G5UzzE8c/

一、看到题目的第一想法

这道题是「有序数组去重,每个元素最多保留两次」,和经典的快慢指针去重题是同类型的变种题。

  1. 核心直觉:因为数组是有序的,重复元素一定是连续的,所以可以用快慢指针来实现「原地修改」,不需要额外空间。
  2. 快慢指针的角色定位
    • fast 指针负责遍历整个数组,寻找符合条件的元素(也就是不会让重复次数超过 2 次的元素)。
    • slow 指针负责维护「有效数组」的末尾位置,记录下一个可以存放新元素的位置。
  3. 边界条件预判:当数组长度 ≤ 2 时,不管元素是否重复,都可以直接返回原长度,因为最多也只有两个元素,天然满足 "不超过两次重复" 的要求。

二、实现过程中遇到的困难

  1. 慢指针起始位置的选择 一开始很容易沿用 "去重保留一次" 的写法,把 slow 初始化为 1。但这道题允许保留两次,前两个元素天然有效,所以 slow 应该从索引 2 开始,直接从第三个元素开始判断是否需要替换。
  2. 判断条件的误区 很容易错误地用 nums[slow-1]nums[fast] 比较,这样会误判 "连续三个相同元素" 的情况。正确的逻辑是:只要 fast 指向的元素,和 slow 维护的有效数组中倒数第二个元素不同,就说明它还没出现过三次,可以加入有效数组 。也就是 nums[slow-2] != nums[fast]
  3. 指针移动的顺序问题 一开始可能会把 ++fast 写在 if 分支里,导致循环中 fast 没有每次都移动,出现死循环或者漏遍历的情况。fast 指针必须在每次循环中都移动,只有满足条件时才移动 slow 指针。
  4. 对 "原地修改" 的理解偏差一开始可能会想着额外开一个数组存结果,忽略了题目要求的「原地修改」和「O (1) 额外空间」限制,而快慢指针刚好能满足这一点。

三、今日收获心得

  1. 快慢指针的通用模板思想 这类「有序数组去重 / 移除指定元素」的题目,快慢指针是通用解法:
    • fast 遍历原数组,筛选有效元素。
    • slow 维护有效数组的写入位置,原地覆盖修改。这道题只是把 "保留一次" 的逻辑改成了 "保留两次",核心框架没有变。
  2. 有序数组的隐藏优势有序数组的重复元素是连续的,这让我们不需要额外的哈希表统计次数,只需要通过和前面固定位置的元素比较,就能判断重复次数,大大优化了空间复杂度。
  3. 边界条件的重要性 一开始处理 numsSize <= 2 的情况,不仅能减少后续循环的无效执行,也避免了数组越界的问题,写算法题时先处理边界条件是个好习惯。
  4. 条件判断的本质理解 这道题的核心条件 nums[slow-2] != nums[fast],本质是在判断「当前元素是否已经在有效数组中出现了两次」,而不是简单的和前一个元素比较。理解了这一点,就可以轻松扩展到 "允许重复 k 次" 的通用场景(只需要把 slow-2 改成 slow-k 即可)。
相关推荐
sugar__salt15 小时前
从栈队列数据结构到JS原型面向对象全解
前端·javascript·数据结构
froyoisle17 小时前
CSP-J 历年复赛 T1 及解析(2019~2025)
数据结构·c++·算法·csp-j·csp·算法竞赛·信息学
喜欢打篮球的普通人18 小时前
LLVM 后端流程与关键数据结构:从 IR 到机器码的入门笔记
java·数据结构·笔记
Misnearch19 小时前
1、数组/字符串
java·数据结构·算法
008爬虫实战录19 小时前
【数据结构】 树、二叉树、完全二叉树,先序遍历、中序遍历、后序遍历
数据结构·算法
AllData公司负责人19 小时前
大模型赋能AllData数据中台,系列升级|通过联合智谱大模型与BiSheng开源项目,建设企业大模型应用开发平台,支持知识库向量检索!
大数据·数据结构·数据库·算法·大模型·向量数据库·智谱ai
梦想的颜色21 小时前
MySQL 数据存储结构与查询执行生命周期深度解析
运维·数据结构·数据库·mysql·线程·优化
Ameilide21 小时前
数据结构 算法解释,排序、查找
数据结构
真实的菜1 天前
Redis 从入门到精通(二):深入数据结构 —— 从 RedisObject 到 SkipList 的源码级拆解
数据结构·redis·skiplist
小欣加油1 天前
leetcode41 缺失的第一个正数
数据结构·c++·算法·leetcode