news 2026/7/27 14:26:28

LeetCode 26 删除有序数组中的重复项

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LeetCode 26 删除有序数组中的重复项

1. 题目

26. 删除有序数组中的重复项 - 力扣(LeetCode)

题目描述

给你一个升序排列的数组nums,请你原地删除重复出现的元素,使每个元素只出现一次 ,返回删除后数组的新长度。

元素的相对顺序应当保持一致。

不要使用额外的数组空间,必须在 (O(1)) 额外空间条件下原地修改输入数组。

无需考虑数组中超出新长度后面的元素。

示例

输入:nums = [1,1,2]

输出:2,nums = [1,2,] 输入:nums = [0,0,1,1,1,2,2,3,3,4] 输出:5,nums = [0,1,2,3,4,,,,,]

约束

  • (1 <= nums.length <= 3 * 10^4)

  • (-10^4 <= nums[i] <= 10^4)

  • nums已按升序排列

2. 最佳解题思路描述(快慢双指针,最优)

  1. 快慢指针定义:

    • slow:慢指针,指向当前有效数组最后一位,初始为 0;

    • fast:快指针,遍历全部数组,逐个寻找新的不重复数字;

  2. 遍历逻辑:

    快指针遇到和nums[slow]不相等的元素,说明是新唯一值;slow++拓展有效区间,把新值覆盖到nums[slow]

  3. 最终有效长度为slow + 1

优势

  • 时间 (O(n)),仅一次遍历;

  • 空间 (O(1)),无 erase、无数组移位;

  • 有序数组去重通用模板,面试首选。

3. 我的可优化代码(逻辑能 AC,但性能差)

class Solution { public: int removeDuplicates(vector<int>& nums) { int n=nums.size(); int m = n; for(int i=0;i<n-1;i++){ if(nums[i]==nums[i+1]){ nums.erase(nums.begin()+i); n--; i--; m--; } } return m; } };

代码说明

  1. 逻辑正确性:

    发现相邻重复元素就 erase 删除,数组长度 n 同步缩减,i 回退重新判断当前位置;m 记录最终长度,能通过所有用例。

  2. 核心缺陷 & 优化点:

    • vectorerase会让删除点后所有元素整体前移,单次 erase 时间 (O(n)),嵌套循环总时间复杂度 (O(n^2)),数据量大时超时;

    • 频繁修改数组长度、回退 i,代码冗余、可读性差;

    • 额外变量 m、n 重复记录长度,无必要。

4. 最优标准代码(快慢双指针)

class Solution { public: int removeDuplicates(vector<int>& nums) { int slow = 0; for (int fast = 1; fast < nums.size(); fast++) { if (nums[fast] != nums[slow]) { slow++; nums[slow] = nums[fast]; } } return slow + 1; } };

5. 总结

  1. 你的 erase 暴力删除写法可以通过测试,但时间效率极低,面试不推荐;

  2. 有序数组原地去重标准解法是快慢双指针,一次遍历无数组删除操作;

  3. 核心规律:慢指针保存唯一值末尾,快指针找新值,不同则拓展有效区间;

  4. 返回长度切记slow + 1,slow 是下标不是长度。

6. 相关知识拓展

拓展 1:同类模板联动

LeetCode27 移除元素、26 有序去重、283 移动零共享快慢指针思想:

快指针筛选有效元素,慢指针维护原地结果数组。

拓展 2:vector erase 性能坑

vector 是连续内存,中间删除元素必须移动后方所有元素;

算法题中应尽量避免循环内频繁 erase,改用双指针覆盖赋值替代删除。

拓展 3:拓展变形(保留最多 2 个重复项 LC80)

仅微调判断逻辑,快慢指针框架不变:

int removeDuplicates(vector<int>& nums) { int slow = 1; for(int fast = 2; fast < nums.size(); fast++){ if(nums[fast] != nums[slow-1]){ slow++; nums[slow] = nums[fast]; } } return slow+1; }

拓展 4:复杂度对比

  1. erase 暴力写法:时间 (O(n^2)),空间 (O(1));

  2. 快慢指针最优解:时间 (O(n)),空间 (O(1))。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/27 14:26:14

LMX9838蓝牙模块多链路与低功耗配置实战指南

1. 项目概述与核心价值在嵌入式蓝牙开发领域&#xff0c;尤其是工业数据采集、多传感器网关或者需要同时连接多个外设&#xff08;如多个串口设备、多个数据终端&#xff09;的场景中&#xff0c;实现稳定、可靠的多点连接一直是个技术难点。很多开发者习惯于点对点&#xff08…

作者头像 李华
网站建设 2026/7/27 14:24:59

Linux设备文件详解:字符设备与块设备的工作原理与应用

1. 设备文件概述 在Linux系统中&#xff0c;设备文件&#xff08;Device File&#xff09;是一种特殊的文件类型&#xff0c;它作为用户空间与硬件设备或内核模块之间的接口而存在。与普通文件不同&#xff0c;设备文件并不存储实际数据&#xff0c;而是充当了访问硬件设备的通…

作者头像 李华
网站建设 2026/7/27 14:23:04

TI bq27505-J4电量计操作配置与电源模式深度解析

1. 项目概述与核心价值在便携式设备和物联网节点这类对功耗极其敏感的应用里&#xff0c;电池管理单元&#xff08;BMU&#xff09;的精度和能效直接决定了产品的用户体验和续航能力。作为这个单元的核心&#xff0c;电量计芯片的角色远不止一个简单的“电量显示条”&#xff0…

作者头像 李华
网站建设 2026/7/27 14:22:47

Minecraft服务器终极管理指南:EssentialsX插件完整教程

Minecraft服务器终极管理指南&#xff1a;EssentialsX插件完整教程 【免费下载链接】Essentials The modern Essentials suite for Spigot and Paper. 项目地址: https://gitcode.com/GitHub_Trending/es/Essentials EssentialsX是Minecraft服务器管理的终极解决方案&am…

作者头像 李华
网站建设 2026/7/27 14:22:20

3大革新功能彻底重塑你的魔兽争霸III游戏体验

3大革新功能彻底重塑你的魔兽争霸III游戏体验 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 你是否还在为经典游戏《魔兽争霸III》在现代电脑上的种种…

作者头像 李华
网站建设 2026/7/27 14:21:47

feTS未来路线图:即将发布的5个令人期待的新功能

feTS未来路线图&#xff1a;即将发布的5个令人期待的新功能 【免费下载链接】feTS &#x1f5f9; TypeScript HTTP Framework focusing on e2e type-safety, easy setup, performance & great developer experience 项目地址: https://gitcode.com/gh_mirrors/fe/feTS …

作者头像 李华