删除有序数组中的重复项II

给定一个已排序的数组,删除重复的元素,使得每个元素最多出现两次,返回新的数组长度。要求在原地修改数组,只使用常数级额外空间,并返回修改后的数组长度。解决方案包括设置两个指针,分别作为快指针和慢指针,通过遍历数组判断元素重复次数不超过两次的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Remove Duplicates from Sorted Array II

​ Given a sorted array nums, remove the duplicates in-place such that duplicates appeared at most twice and return the new length.

​ Do not allocate extra space for another array; you must do this by modifying the input array in-place with O(1) extra memory.

Clarification:

​ Confused why the returned value is an integer, but your answer is an array?

​ Note that the input array is passed in by reference, which means a modification to the input array will be known to the caller.

​ Internally you can think of this:

​ //nums is passed in by reference. (i.e, without making a copy)

​ int len = removeDuplicates(nums);

​ //any modification to nums in your function would be known by the caller.

​ //using the length returned by your function, it prints the first len elements.

​ for(int i = 0; i < len; i++) {

​ print(nums[i]);

​ }

在这里插入图片描述

今天的题目是去除有序数组中的重复元素,不过这次不是一个元素只能出现一次了,相同的元素最多可以出现两次。而且,本题还要求在输入数组上进行操作,不能占用额外的内存空间,要求最后返回保留的数组的长度n,且输入数组的前n项要正好是我们最后保留的元素。

​ 对于这道题,我们可以维护两个指针(或者说索引),快指针指向我们当前判断的元素,慢指针指向我们保留的最后一个元素的索引+1,即慢指针正好是最终题目要求的结果——保留的数组的长度,当我们判定快指针指向的元素重复的次数没有超过2时,就将快指针所指的元素赋值给慢指针所指向的位置,同时慢指针++,否则慢指针不动,快指针继续向后遍历。

​ 当然,我们还要考虑到一些特殊的情况。当输入数组的长度小于等于2时, 元素一定不会出现重复,所以直接返回原数组即可。而且,当数组长度大于2时,数组的前2个元素也是一定会被保留下来的,所以我们定义的两个指针只需从2开始判断。

​ 实现的代码如下:

public class Solution {

    public int removeDuplicates(int[] nums) {
        int len = nums.length;
        if(len <= 2) {          //如果数组长度小于等于2,则无论如何都不需要去重,直接返回即可
            return len;
        }

        int slow = 2, fast = 2;     //定义两个指针,一个快指针一个慢指针,快指针表示当前检查到的元素的索引,慢指针表示被保留的最后一个元素的索引
        while(fast < len) {
            if(nums[slow-2] != nums[fast]) {    //由于相同元素最多出现两次,因此需要判断当前元素与上上一个保留的元素是否相等
                nums[slow] = nums[fast];
                slow++;
            }
            fast++;
        }
        return slow;
    }
}

完美解决问题,今日每日一题结束。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值