6Hzlia头像
关注
【Classic 150 刷题计划】 LeetCode 26. 删除有序数组中的重复项 | C++ 快慢双指针经典模板封面图

【Classic 150 刷题计划】 LeetCode 26. 删除有序数组中的重复项 | C++ 快慢双指针经典模板

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:负责在前面开路,遍历寻找与慢指针所指元素不同的“新元素”。它就像一个“侦察兵”。

核心动作:

  1. 初始状态下,l = 0r = 1。因为数组的第一个元素绝对是不重复的,直接保留。
  2. 快指针 r 不断向右移动,逐个考察元素:
    • 如果 nums[r] == nums[l]:说明是重复元素,侦察兵直接跳过,继续往前探。
    • 如果 nums[r] != nums[l]:说明侦察兵找到了一个全新的元素!我们就把这个新元素扔到守门员的下一个位置 nums[l+1] = nums[r],然后守门员 l 往前跟进一步,将新元素纳入保护区。
  3. 循环结束后,慢指针 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

文章来源转载

评论

赞0

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--