InterviewGuide 力扣刷题笔记:80. 删除排序数组中的重复项 II——原地去重的双指针通用解法
文档教程知识库【免费下载链接】InterviewGuide「InterviewGuide」是阿秀从校园-职场多年计算机自学过程的记录以及学弟学妹们计算机校招秋招经验总结文章的汇总包括但不限于C/C 、Golang、JavaScript、Vue、操作系统、数据结构、计算机网络、MySQL、Redis等学习总结坚持学习持续成长项目地址https://gitcode.com/forthespada/InterviewGuide点击查看免费下载本文是《InterviewGuide》精选力扣 300 道算法题系列中“双指针”标签下的一道 Medium 题解。围绕阿秀刷题笔记中的原始解法从题目约束、引用传递机制、代码逐行拆解到复杂度论证讲透“有序数组原地去重、每个元素最多保留两次”这一经典套路并推广出可复用的“最多保留 k 次”通用模板帮助你从容应对面试中的同族变体题。题目回顾LeetCode 80. 删除排序数组中的重复项 II给定一个排序数组你需要在原地删除重复出现的元素使得每个元素最多出现两次返回移除后数组的新长度。不要使用额外的数组空间你必须在原地修改输入数组并在使用O(1) 额外空间的条件下完成。示例 1:给定 nums [1,1,1,2,2,3], 函数应返回新长度 length 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2, 3 。 你不需要考虑数组中超出新长度后面的元素。示例 2:给定 nums [0,0,1,1,1,1,2,3,3], 函数应返回新长度 length 7, 并且原数组的前五个元素被修改为 0, 0, 1, 1, 2, 3, 3 。 你不需要考虑数组中超出新长度后面的元素。原笔记将其标注为“很好的题目”原因在于它表面是“删除重复元素”的简单任务实则隐藏着双指针压缩、条件后移这两大高频面试考点是 LeetCode 26. 删除排序数组中的重复项每个元素最多保留一次的升级版。为什么返回的是整数输出的却是数组题目说明中特别强调输入数组是以“引用”方式传递的这意味着在函数里修改输入数组对于调用者是可见的。你可以想象内部操作如下// nums 是以引用方式传递的。也就是说不对实参做任何拷贝 int len removeDuplicates(nums); // 在函数里修改输入数组对于调用者是可见的。 // 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。 for (int i 0; i len; i) { print(nums[i]); }这正是“原地in-place算法”的评测惯例判题系统不关心数组尾部残留的旧数据只按你返回的len截取前len个元素进行校验。因此解题时只需保证新序列紧挨在数组头部超出新长度的部分可以任意残留无需真正删除或缩容。核心思路一个“写指针”完成的原地压缩对于已经排好序的数组相同元素必然连续成段。要让每个元素最多出现两次等价于扫描整个数组时只要当前位置的元素不与“已保留序列中倒数第二个元素”相同就可以安全地把它写入新序列的尾部。这样整个数组只被扫描一遍且就地写入不需要开辟任何辅助数组天然满足 O(1) 额外空间的要求。从实现形态上看这属于双指针思想中“快慢指针”的变体——i是快指针只读扫描len是慢指针写位置两者共用同一个数组。第一版解法阿秀原解简洁到极致的双指针原笔记给出的解法很短执行用时 12 ms、内存消耗 8.9 MB作者当时在 C 提交中的记录分别击败约 98.85% 与 73.46% 的用户int removeDuplicates(vectorint nums) { int len 0; for (int i 0; i nums.size(); i) { if (len 2 || nums[i] ! nums[len-2]) nums[len] nums[i]; } return len; }原笔记参考了评论区大佬的解法下面把各个步骤和变量的含义完整展开len表示的是删除重复元素后新序列的长度同时也表示新元素进入新序列的索引即下一个写入位置i就是循环变量用于遍历整个旧序列if (len 2) nums[len] nums[i];的意思是如果新序列的长度小于 2即新序列中不会存在两个相同的元素此时i位置所在元素不可能与新序列中已有的两个元素构成三个相同元素直接将新元素加入到新序列中并更新新序列的长度if (nums[i] ! nums[len-2]) nums[len] nums[i];的意思是如果新元素加入后不会和前两个元素构成 3 个相同的元素nums[len-2]就是直接取新序列中倒数第二个元素如果该元素和新元素相同说明加入后会构成 3 个相同的元素显然不符合题意就将新元素加入到新序列中并更新新序列的长度题意只要求将新序列紧挨在一起就行多出的长度将不参与评测。正确性论证为什么这样写必然成立可以分三步论证这段代码的正确性前两个元素无条件保留。len 2时直接写入保证新序列长度至少为 2 前不受任何限制。因为一个元素出现两次总是被允许的前两个元素无论相同与否都必然合法。从第三个元素起只需与“倒数第二个”比较。由于数组有序且已保留的新序列同样有序若nums[i]与nums[len-2]相同则它必然也与nums[len-1]相同中间夹着的元素只可能是同一个值此时再写入就会形成 3 连重复必须丢弃反之若与nums[len-2]不同则无论与nums[len-1]是否相同最多只会形成 2 连重复写入后依然合法。写入位置len单调不减且永远不会越过读取位置i写入量 ≤ 读取量因此覆盖操作是安全的不会破坏后续待读取的数据。复杂度分析时间复杂度O(n)。整个数组只被for循环扫描一遍每次迭代仅做常数次比较与赋值其中 n 为数组长度空间复杂度O(1)。全程没有申请与 n 相关的辅助存储仅使用了len、i两个整型变量满足题目“不要使用额外的数组空间”的硬性约束。这正是面试官期待的最优解一趟扫描 常数空间无法再被优化。推广把“最多两次”泛化成“最多 k 次”从上面的正确性论证可以看出比较基准nums[len-2]中的数字 2 正是题目允许的最大重复次数。把它替换成任意常数k就得到“每个元素最多保留 k 次”的通用模板int removeDuplicates(vectorint nums, int k) { // k 2 即本题 int len 0; for (int i 0; i nums.size(); i) { if (len k || nums[i] ! nums[len - k]) nums[len] nums[i]; } return len; }当k 1时该模板退化为 LeetCode 26 题每个元素最多保留一次的经典快慢指针解法当k 2时即本题。面试中只要讲清“为什么是与len-k位置比较”这一句就能向面试官证明你吃透了这族题目的本质而不是死记硬背代码。从源码到面试本专题的延伸阅读本题收录于 InterviewGuide 仓库的 双指针专题目录Medium 分组聚合版题解可见 total/08-双指针/medium/medium.md同一专题下的 75. 颜色分类 同样是原地修改数组的代表题其“第二版”用到了双路快排的思想可与本题对照学习若想系统补齐数组原地操作与双指针的其他形态相向指针、滑动窗口等可先阅读仓库的 算法基础部分再按 力扣刷题笔记专栏说明 中的 13 个标签逐个击破。面试中遇到本题时建议按“题目约束 → 有序性利用 → 写指针压缩 → 泛化到 k 次”这条链路作答先说思路再写代码最后补上复杂度分析即可构成一次完整、扎实的算法面试回答。赞分享文档教程知识库【免费下载链接】InterviewGuide「InterviewGuide」是阿秀从校园-职场多年计算机自学过程的记录以及学弟学妹们计算机校招秋招经验总结文章的汇总包括但不限于C/C 、Golang、JavaScript、Vue、操作系统、数据结构、计算机网络、MySQL、Redis等学习总结坚持学习持续成长项目地址https://gitcode.com/forthespada/InterviewGuide点击查看免费下载相关推荐LeetCode 26. 删除排序数组中的重复项快慢指针读写指针原地去重题解LeetCode 26. 删除排序数组中的重复项快慢指针读写指针原地去重题解 本文以 leetcode 题解仓库 gh_mirrors/le/leetc文档教程知识库LogicStack-LeetCode 题解80. 删除有序数组中的重复项 II —— 双指针与「保留 k 位」通解实战LogicStack LeetCode 题解80. 删除有序数组中的重复项 II —— 双指针与「保留 k 位」通解实战 本篇技术指南以「宫水三叶的刷题日记」教程文档YCBlogs 算法笔记排序数组原地去重LeetCode 26的双指针实现与复杂度分析YCBlogs 算法笔记排序数组原地去重LeetCode 26的双指针实现与复杂度分析 本篇基于 YCBlogs 仓库中 从数组中删除重复项 https:教程技术博客文档创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

AnyPS5:PS5存储扩展、外设兼容与网络优化全攻略

AnyPS5:PS5存储扩展、外设兼容与网络优化全攻略

说实话,一开始想做“AnyPS5”这个项目的动机挺简单的:我自己手头有几台不同批次、不同使用时长、甚至连摆放环境都完全不一样PS5主机。有朋友来家里玩,都会问同样的问题——为什么我这台开游戏就是快一点?为什么他那台插个手柄总是…

2026/10/13 4:57:19 阅读更多 →
Hermes Agent入门:轻量级协议语义翻译器实战指南

Hermes Agent入门:轻量级协议语义翻译器实战指南

1. 为什么“Hermes Agent”突然被大量开发者同时提及?最近两周,我在几个技术交流群和内部项目复盘会上,连续听到不同背景的开发者提到同一个词:Hermes Agent。不是Hermes引擎、不是React Native的Hermes JS引擎,而是带…

2026/10/13 4:57:19 阅读更多 →
Android ANR问题全链路分析:从判定机制到测试解决方案

Android ANR问题全链路分析:从判定机制到测试解决方案

我最早接触ANR,是线上用户反馈一个列表页“点了没反应”,过一会儿系统弹窗“进程无响应”。当时拿着一个logcat日志,翻来覆去只能看到一行“ANR in”,完全不知道怎么下手。后来带测试团队、又参与线上性能治理,踩了无数…

2026/10/13 4:56:18 阅读更多 →

最新新闻

IIS管理器打开全攻略:本机启动、远程连接与排错实战

IIS管理器打开全攻略:本机启动、远程连接与排错实战

搞Windows服务器的同学都清楚,IIS管理器这个窗口,看着不起眼,却是撑起大量Web业务的关键工具。很多人以为它就是个“打开就能用”的图形界面,但在实际运维里,光是怎么把它顺利打开、正常连上远程站点,就能筛…

2026/10/13 5:33:32 阅读更多 →
从compose到组合上下文:函数组合的工程化实战复盘

从compose到组合上下文:函数组合的工程化实战复盘

函数组合不是新东西,但真正把它做到"极致"和"优雅",我用了将近一年的时间反复打磨。这篇文章是我对这段时间的完整复盘。我不打算讲枯燥的范畴论,也不打算罗列一堆库的API,我想说的是:我如何从一个…

2026/10/13 5:33:32 阅读更多 →
充电器空载发热、待机功耗异常怎么办?温度保险电阻排查维修实战

充电器空载发热、待机功耗异常怎么办?温度保险电阻排查维修实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 5:33:32 阅读更多 →
fio-3.8完整指南:从解压编译到IOPS与延迟分析实战

fio-3.8完整指南:从解压编译到IOPS与延迟分析实战

简介:FIO(Flexible I/O Tester)3.8 版本完整源代码压缩包,面向存储性能测试工程师、系统运维与内核/驱动开发者,用于在 SSD、HDD、RAID、NVMe 等场景下评估读写吞吐、IOPS 与延迟,并开展压力测试与瓶颈定位…

2026/10/13 5:33:32 阅读更多 →
python -v 和 python -V 的区别:命令行参数大小写敏感与解释器启动排查

python -v 和 python -V 的区别:命令行参数大小写敏感与解释器启动排查

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 5:33:32 阅读更多 →
目标类型new表达式:现代编程语言的类型推断演进

目标类型new表达式:现代编程语言的类型推断演进

1. 目标类型new表达式的前世今生第一次看到var list new List<string>();这种写法时&#xff0c;我还在用Java写ArrayList<String> list new ArrayList<String>();。这种重复的类型声明总让我觉得像在说废话——明明右边已经写了类型&#xff0c;为什么左边…

2026/10/13 5:32:32 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目&#xff0c;我最大的感受是&#xff0c;大部分坑不是出在技术前沿&#xff0c;而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节&#xff0c;最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了&#xff0c;很难不碰到舵机控制这道坎。做智能小车要转方向&#xff0c;做机械臂要抬关节&#xff0c;做云台要偏航俯仰&#xff0c;背后都是同一个东西在干活&#xff1a;舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”&#xff1f;——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台&#xff1f;或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜&#xff1f;又或者&#xff0c;在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介&#xff1a;基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码&#xff0c;面向计算机相关专业课程设计与期末大作业学生&#xff0c;以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程&#xff0c;…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程&#xff1a;键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化&#xff0c;十个新手有八个栽在"往输入框里填东西"这件事上&#xff1a;要么填不进去&#xff0c;要么填了一半&#xff0c;要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程&#xff1a;阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀&#xff1a;什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面&#xff0c;跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →