双指针算法实现有序数组去重与LeetCode 26题解析

发布时间:2026/10/31 16:14:30

双指针算法实现有序数组去重与LeetCode 26题解析 1. 问题背景与需求分析在算法面试和日常编程中处理有序数组的去重操作是一个经典问题。LeetCode第26题删除有序数组中的重复项要求我们原地修改输入数组使得每个元素只出现一次并返回新的长度。这个问题看似简单但考察了几个关键编程能力对数组数据结构的理解双指针算法的应用原地修改数组的技巧边界条件的处理能力实际业务场景中类似操作也很常见。比如处理日志数据时去除连续重复条目数据库查询结果去重时间序列数据的清洗2. 问题描述与示例给定一个非严格递增排列的数组nums原地删除重复出现的元素使每个元素只出现一次。返回删除后数组的新长度。要求必须原地修改输入数组使用O(1)额外空间元素的相对顺序必须保持一致示例1 输入nums [1,1,2] 输出2, nums [1,2,_] 解释函数应返回长度2原数组前两个元素修改为1和2示例2 输入nums [0,0,1,1,1,2,2,3,3,4] 输出5, nums [0,1,2,3,4,,,,,_]3. 双指针解法详解3.1 基本思路最直观的解法是使用双指针技术慢指针(slow)指向当前唯一元素的最后一个位置快指针(fast)遍历数组寻找下一个不重复元素当找到不重复元素时将其复制到slow1位置然后slow前进这种方法的优势在于时间复杂度O(n)只需遍历一次数组空间复杂度O(1)只使用了常数个额外变量保持了元素的原始顺序3.2 代码实现def removeDuplicates(nums): if not nums: return 0 slow 0 for fast in range(1, len(nums)): if nums[fast] ! nums[slow]: slow 1 nums[slow] nums[fast] return slow 13.3 执行过程分析以nums [0,0,1,1,1,2,2,3,3,4]为例初始状态 slow0, fast1 nums[1]0 nums[0]0 → 不操作fast2: nums[2]1 ! nums[0]0 → slow1, nums[1]1 数组变为[0,1,1,1,1,2,2,3,3,4]fast3: nums[3]1 nums[1]1 → 不操作fast4: nums[4]1 nums[1]1 → 不操作fast5: nums[5]2 ! nums[1]1 → slow2, nums[2]2 数组变为[0,1,2,1,1,2,2,3,3,4]fast6: nums[6]2 nums[2]2 → 不操作fast7: nums[7]3 ! nums[2]2 → slow3, nums[3]3 数组变为[0,1,2,3,1,2,2,3,3,4]fast8: nums[8]3 nums[3]3 → 不操作fast9: nums[9]4 ! nums[3]3 → slow4, nums[4]4 最终数组[0,1,2,3,4,2,2,3,3,4] 返回长度54. 边界条件与特殊情况处理4.1 空数组处理当输入数组为空时应直接返回0。这是最容易忽略的边界情况。if not nums: return 04.2 单元素数组数组只有一个元素时无需任何操作直接返回1。4.3 全相同元素数组如nums [1,1,1,1]应返回1数组变为[1,,,_]4.4 已去重数组如nums [1,2,3,4]应返回4数组保持不变5. 算法复杂度分析时间复杂度O(n)只需一次遍历数组每个元素最多被访问一次空间复杂度O(1)只使用了slow和fast两个额外变量6. 变种问题与扩展6.1 允许最多保留k个重复项LeetCode第80题是此问题的扩展要求每个元素最多出现两次。通用解法def removeDuplicates(nums, k2): if len(nums) k: return len(nums) slow k for fast in range(k, len(nums)): if nums[fast] ! nums[slow - k]: nums[slow] nums[fast] slow 1 return slow6.2 无序数组去重如果数组无序可以使用哈希表记录已出现元素def removeDuplicates(nums): seen set() slow 0 for fast in range(len(nums)): if nums[fast] not in seen: seen.add(nums[fast]) nums[slow] nums[fast] slow 1 return slow但这种方法空间复杂度为O(n)不符合本题要求。6.3 返回新数组而非修改原数组如果允许返回新数组可以直接使用集合def removeDuplicates(nums): return list(set(nums))但会丢失元素顺序且空间复杂度为O(n)7. 实际应用场景7.1 数据库查询结果去重SELECT DISTINCT column FROM table在内存中处理时可能需要类似的去重算法7.2 日志处理去除连续的重复日志条目减少存储空间7.3 时间序列数据清洗去除传感器采集的重复数据点8. 常见错误与调试技巧8.1 数组越界错误忘记检查数组是否为空直接访问nums[0]会导致错误8.2 逻辑错误错误地将slow指针初始化为1导致第一个元素被跳过8.3 测试用例建议应测试以下情况空数组单元素数组全相同元素数组已去重数组常规有重复数组8.4 调试技巧可以在循环中加入打印语句观察指针移动和数组变化print(fslow{slow}, fast{fast}, nums{nums})9. 性能优化与语言特性9.1 Python中的优化在Python中列表操作可能较慢。对于大型数组可以考虑使用numpy数组import numpy as np def removeDuplicates(nums): nums np.array(nums) if len(nums) 0: return 0 slow 0 for fast in range(1, len(nums)): if nums[fast] ! nums[slow]: slow 1 nums[slow] nums[fast] return slow 19.2 C实现int removeDuplicates(vectorint nums) { if (nums.empty()) return 0; int slow 0; for (int fast 1; fast nums.size(); fast) { if (nums[fast] ! nums[slow]) { nums[slow] nums[fast]; } } return slow 1; }9.3 Java实现public int removeDuplicates(int[] nums) { if (nums.length 0) return 0; int slow 0; for (int fast 1; fast nums.length; fast) { if (nums[fast] ! nums[slow]) { nums[slow] nums[fast]; } } return slow 1; }10. 面试技巧与注意事项10.1 面试官可能问的问题为什么选择双指针解法如何处理边界条件时间复杂度和空间复杂度是多少如何测试你的代码如果数组很大如何优化10.2 回答技巧先明确问题要求和约束条件解释算法思路画图说明指针移动主动讨论边界条件和测试用例分析复杂度讨论优化可能性10.3 代码风格建议添加有意义的变量名slow/fast比i/j更好添加必要的注释先处理边界条件保持代码简洁但可读11. 相关题目推荐LeetCode 27 - 移除元素LeetCode 80 - 删除有序数组中的重复项 IILeetCode 283 - 移动零LeetCode 844 - 比较含退格的字符串LeetCode 977 - 有序数组的平方12. 学习资源与进阶《算法导论》 - 基础算法部分《编程珠玑》 - 数组处理技巧LeetCode探索卡片 - 数组与字符串双指针算法专题原地算法(in-place algorithm)研究在实际刷题过程中我发现理解双指针的核心思想比记忆特定解法更重要。这个问题的关键在于认识到我们可以利用数组的有序性通过比较相邻元素来识别重复项。这种模式可以推广到许多其他数组处理问题中。
延伸阅读

更多相关文章

2026/10/31 16:14:30

机器学习与深度学习技术全景解析及实践指南

1. 机器学习与深度学习技术全景解析在当今数据驱动的时代,机器学习(ML)和深度学习(DL)已成为最炙手可热的技术领域。作为人工智能的核心支柱,它们正在重塑各行各业的业务模式和技术架构。不同于传统编程,这些技术让计算机能够从数据中自动学习…

2026/10/31 16:14:30

AI智能体编程趋势报告解读:从补全代码到托管任务

Anthropic这份《2026年AI智能体编程趋势报告》出来之后,我身边做研发的朋友看法很分裂。有人觉得是厂商造势,有人觉得这次是真的变量。我花了两周时间把它读完,又结合我们自己团队过去一年在AI智能体上的实际落地情况,想认真聊聊这…

2026/10/31 16:14:30

LabVIEW多通道测试框架设计与优化实践

1. 项目概述:多通道测试框架的核心价值在自动化测试领域,多通道并行测试能力直接决定了系统效率和成本效益。这个LabVIEW多通道测试程序模板解决了传统测试方案中的三个痛点:首先,通过标准化VI接口规范,实现了测试模块…

2026/10/31 18:34:39

Windows下Python脚本服务化部署方案详解

1. Windows服务化Python脚本的核心需求在企业级应用和自动化运维场景中,我们经常需要将Python脚本作为后台服务持续运行。典型的应用场景包括:实时监控系统资源的守护进程定时执行数据同步任务的调度器提供API接口的微服务应用工业控制领域的设备通信网关…

2026/10/31 18:34:39

开源PPT自动化方案:Mermaid/Excalidraw/PlantUML实战指南

1. 这三款开源工具,真能替代PPT设计师和架构师?最近在几个技术团队的内部分享会上,我被反复问到一个问题:“现在AI画图、AI做PPT到底靠不靠谱?能不能真用在项目汇报、客户交付、技术评审这些正式场合?”不是…

2026/10/31 18:34:39

工业软件如何真正‘会思考’:从图纸到工程决策的AI落地路径

1. 这不是给软件加个“AI按钮”,而是重构工程师的思考路径“工业软件的AI落地实录:从画图纸到会思考的软件”——这个标题里藏着一个被行业长期回避的真相:过去十年,太多工业软件厂商把AI当成了PPT里的装饰词,或是产品…

2026/10/31 18:34:39

工业AI落地避坑指南:为什么‘全产线覆盖’是最大误区

1. 这句话为什么让工程师头皮发麻——从产线现场看“全产线覆盖”的真实代价“90%的工业AI项目,都死在老板一句‘全产线覆盖’上”——这不是段子,是我在过去八年跑遍长三角、珠三角37家制造企业后,亲手记下的21个失败案例里,出现…

2026/10/31 18:34:39

GitHub命令行操作指南与SSH配置详解

1. 为什么选择纯命令行操作GitHub?在图形化界面大行其道的今天,很多开发者可能会疑惑:为什么还要学习命令行操作GitHub?作为一个在Linux环境下工作多年的老码农,我可以很负责任地告诉你,命令行操作GitHub至…

2026/10/31 18:29:39

字符级RNN文本生成:从原理到莎士比亚风格实现

1. 项目概述:字符级RNN文本生成的核心逻辑字符级RNN文本生成器就像一位数字时代的莎士比亚学徒,它通过逐字"咀嚼"大量文本数据来学习语言模式。与常见的单词级模型不同,字符级模型以单个字符为基本单位(包括字母、标点和…

2026/10/30 20:55:10

全国计算机二级C语言真题PDF高效刷题指南

简介:这份PDF是全国计算机二级C语言考试的试题与答案解析,专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/30 20:55:10

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介:一份以实战为导向的Python爬虫入门资源,面向具备基本编程基础、希望快速掌握网络数据抓取的初学者,可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档,完整演示从网页中提取 标题…

2026/10/30 20:55:09

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介:这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档,压缩包大小七十八KB,内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开:先构造一个极点位于单位圆内…

2026/10/31 0:02:41

猫狗目标检测数据集:VOC/COCO/YOLO三格式一体化实战包

简介:本资源是一套面向计算机视觉初学者与YOLO目标检测实践者的猫狗图像数据集及配套开发工具包,专为快速上手目标检测模型训练而设计。资源包含1000张真实场景高清猫狗图片,标注质量高,同时提供VOC(XML)、…

2026/10/31 0:02:41

HDU2017多校标程复现:算法竞赛工程化真题沙盒

简介:本资源为2017年HDU多校联合训练第一场官方配套资料,面向ACM程序设计竞赛备赛学生、算法爱好者及高校编程集训队成员,旨在提供权威解题参考与完整测试验证环境。压缩包共40个文件,含15份C标程(覆盖全部赛题&#x…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑