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

题目

给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。

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

示例 1:

输入: nums = [1,1,2]
输出: 2, nums = [1,2]
解释: 函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 。不需要考虑数组中超出新长度后面的元素。

示例 2:

输入: 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 。不需要考虑数组中超出新长度后面的元素。

考点(模式识别)

  • 双指针法的应用:本题主要考查利用快慢指针的模式来解决在特定约束(原地修改、空间复杂度 O(1))下的数组元素去重问题。通过合理移动快慢指针,能够高效地遍历数组并完成去重操作,是对数组操作和指针运用的典型考查。
  • 对排序数组特性的利用:题目给定的是排序数组,正是利用排序后相同元素相邻的这一特性,才能方便地通过比较相邻元素来判断是否重复,进而实现去重逻辑。

所有解法

  1. 双指针法(快慢指针):这是解决本题最常用也是较高效的方法,通过定义快慢两个指针,慢指针指向去重后数组的最后一个有效位置,快指针用于遍历整个数组,当快慢指针所指元素不同时,将快指针指向的元素复制到慢指针的下一个位置,以此实现去重。

解题步骤(双指针法)

  1. 初始化两个指针,slow 指针初始化为 0,代表去重后数组的末尾位置;fast 指针从 1 开始,用于遍历整个数组(因为要和 slow 指针所指元素比较,slow 初始位置为 0,所以 fast 从 1 开始合适)。
  2. 开始遍历数组(通过移动 fast 指针),当 nums[fast]nums[slow] 不相等时,意味着发现了一个新的不重复元素。
    • nums[fast] 赋值给 nums[slow + 1],相当于把新的不重复元素放到去重后数组的合适位置(也就是 slow 指针的下一个位置)。
    • 然后将 slow 指针向后移动一位(slow++),更新去重后数组的末尾位置。
  3. fast 指针遍历完整个数组后,slow + 1 的值就是去重后数组的长度,因为 slow 指向的是去重后数组的最后一个有效元素的位置。

C 语言实现(双指针法)

// 函数功能:使用双指针法原地删除排序数组中的重复元素,并返回去重后数组的新长度
// 参数 nums:指向整型数组的指针,代表要处理的排序数组
// 参数 numsSize:整型,代表数组 nums 的元素个数
int removeDuplicates(int* nums, int numsSize) {
    if (numsSize == 0) {  // 如果数组为空,直接返回 0
        return 0;
    }
    int slow = 0;  // 慢指针,指向去重后数组的末尾位置,初始化为 0
    for (int fast = 1; fast < numsSize; fast++) {  // 快指针遍历数组,从 1 开始
        if (nums[fast]!= nums[slow]) {  // 当快慢指针所指元素不同时
            slow++;  // 先将慢指针向后移动一位
            nums[slow] = nums[fast];  // 将快指针指向的元素复制到慢指针位置
        }
    }
    return slow + 1;  // 返回去重后数组的新长度(slow 指向最后一个有效元素,长度为 slow + 1)
}

上述代码中,首先判断了数组是否为空的特殊情况,如果为空则直接返回 0。然后利用 for 循环让快指针 fast 遍历数组,在循环内部,通过比较快慢指针所指元素是否相同来决定是否进行去重操作(即移动慢指针并复制元素),最后返回去重后数组的新长度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

请向我看齐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值