LeetCode 26. 删除有序数组中的重复项
📌 题目描述
题目级别:简单
给你一个 非严格递增排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。
要求:必须在 原地 修改输入数组,使用 O(1)O(1)O(1) 额外空间。
- 示例 1:
输入:nums = [0,0,1,1,1,2,2,3,3,4]
输出:5,nums = [0,1,2,3,4]
解释:函数应该返回新的长度 5 , 并且原数组nums的前五个元素被修改为 0, 1, 2, 3, 4 。不需要考虑数组中超出新长度后面的元素。
💡 破题思路:快慢双指针 (原地覆盖)
面对“原地修改”且“保持相对顺序”的数组题目,快慢双指针是绝对的首选武器。由于数组是有序的,这就意味着所有重复的元素必然是连续挨在一起的。
- 慢指针
l:指向目前已经处理好的、没有重复元素的数组的最后一个位置。它就像一个“守门员”,守护着已经去重完毕的纯净区域。 - 快指针
r:负责在前面开路,遍历寻找与慢指针所指元素不同的“新元素”。它就像一个“侦察兵”。
核心动作:
- 初始状态下,
l = 0,r = 1。因为数组的第一个元素绝对是不重复的,直接保留。 - 快指针
r不断向右移动,逐个考察元素:- 如果
nums[r] == nums[l]:说明是重复元素,侦察兵直接跳过,继续往前探。 - 如果
nums[r] != nums[l]:说明侦察兵找到了一个全新的元素!我们就把这个新元素扔到守门员的下一个位置nums[l+1] = nums[r],然后守门员l往前跟进一步,将新元素纳入保护区。
- 如果
- 循环结束后,慢指针
l的下标就代表了最后一个不重复元素的位置,那么去重后的有效数组长度就是l + 1。
💻 C++ 代码实现 (原汁原味作者版)
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
int n = nums.size();
// 边界情况:如果数组只有一个元素,必定无重复,直接返回 1
if (n == 1) return 1;
// 定义快慢双指针
int l = 0, r = 1;
// 快指针 r 负责探路,直到遍历完整个数组
while (r < n)
{
// 如果发现了全新的元素
if (nums[l] != nums[r])
{
// 将新元素覆盖到慢指针的下一个位置
nums[l + 1] = nums[r];
// 慢指针向前推进一步,纳入该新元素
l ++ ;
}
// 无论是否重复,快指针始终向前走
r ++ ;
}
// l 是最后一个不重复元素的下标,有效长度就是 l + 1
return l + 1;
}
};
转载自 CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/qq_51233453/article/details/165225679




