删除有序数组中的重复项

方法:双指针

题目要求:对给定的有序数组 numsnums 删除重复元素,在删除重复元素之后,每个元素只出现一次,并返回新的长度,上述操作必须通过原地修改数组的方法。

由于给定的数组是有序的,所以数组的元素是按照从小到大排序,因此对于任意的i<j,如果有

nums[i]=nums[j],那么对于任意的 i\leq k\leq j ,一定有 nums[i]=nums[k]=nums[j] 

通俗的讲,对于两个相同元素之间的元素,一定也相同。

题目要求更改数组 nums ,使 nums 的前 k 个元素包含唯一元素,并按照它们最初在 nums 中出现的顺序排列。nums 的其余元素与 nums 的大小不重要。所以可以考虑用双指针的方法来做。

双指针的意思就是定义两个指针,分别指向数组的某个元素,比如两个元素分别为慢指针和快指针,那么,快指针就负责遍历整个数组的各个元素,而慢指针用来与快指针进行比较,来进一步的更新原数组,使得数组最终满足题目要求。

在数组长度小于2的时候,也就是1或0时,数组无需改动,直接返回数组长度即可。当数组大于1时,第一个元素实际上也无需变动,所以只需要从下标为1的元素开始即可。所以可以定义两个指针的初始值都为1,然后快指针遍历数组元素,遍历到与上一个元素不一样时,交给慢指针,更新原数组,然后慢指针向后一位,重复操作,直至遍历完整个数组为止。

这里可以举个例子:例如如下数组 {0,0,1,1,1,2,2,3,3},完整的过程如下:

首先定义两个指针初始值为1。

 快指针开始遍历数组,指向2的位置,判断前后的元素,发现0不等于1,则把该值赋给慢指针。即如下图:

然后慢指针会指向下一个元素,如图所示:

 

接下来重复操作,直到快指针指向5的时候,也就是元素2,判断与上一个元素不同,则把2这个值赋给慢指针,如下图所示:

接下来,直到快指针遍历到元素3的时候,会把这个值赋给慢指针,如图所示:

最终,数组就完成遍历以及更新,如图所示:

整体的思路就是这样,C++代码实现如下:

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

复杂度分析

时间复杂度:O(n),其中n是数组的长度。快指针和慢指针最多各移动n次

空间复杂度:O(1)。只需要使用常数的额外空间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值