leetCode26:Remove Duplicates from Sorted Array


Given a sorted array, remove the duplicates in place such that each element appear only once and return the new length.

Do not allocate extra space for another array, you must do this in place with constant memory.

For example,
Given input array nums = [1,1,2],

Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively. It doesn't matter what you leave beyond the new length.

问题需求:

1,删除有序顺序表里面的重复元素,若任一元素出现了超过一次,只需留下一次即可。

2,不能开辟新的数组或者申请内存空间,所有改动都只能在原数组那修改,算法空间复杂度只能是常数。

问题分析:

1,边界条件:当数组的元素个数等于零个或者一个,不用进行任何处理,只要直接返回就可以了。

2,基于上述,算法设计只要考虑元素个数大于等于两个即可。

3,最简单粗暴的方法就是,逐一比较相邻两个元素,一旦发现有相等的,就将后面元素全部前移,覆盖掉相等的那个元素,但是这个方法实在太耗时了。

4,不再考虑移动元素方法,而是考虑“更新”元素。

解题思路:如图



1,采用双指针法解题(不是真的定义两个指针,而是定义两个整型记录下标),p代表了数组最后一个有效数据位置,q表示了那些用来作对比的数据。

2,p从首个元素开始(注意此时下标是零),比较角标为(p+1)的元素,是否大于角标为p那个元素。

(1)如果大于,p++(即p前移)。

(2)否则,p暂时不要移动,让q指向(p+1)号元素,然后比较元素q是不是大于元素p。如果大于,将p+1号元素里面的值“更新”为q号元素的值,然后两个指针均要前移;否则,不对元素做“更新”操作,而q继续向前移动,但p不要向前移动。

3,循环执行2-(2)步骤所示比较操作以及比较结果处理方式,但是注意不要再q = p+1(这个操作只是用在q被启用那时候的),当q走到数组末尾,表示所有元素已经比较完了,返回就可。

4,注意每次“更新”元素,记录新数组元素个数的那个变量都要加一。

代码如下:

int removeDuplicates(int* nums, int numsSize) {
    int returnSize = 1;//记录新数组的元素个数
    int p = 0,q = 0;//这两个是工作指针
    if(numsSize==0||numsSize==1) return numsSize;//边界条件直接返回
    while(p+1<=numsSize-1){//确保p+1不越界
        if(nums[p+1]>nums[p]){//如果不是重复元素
            p++;
            returnSize++;
        }else{
            q = p+1;
            while(q<numsSize){
                if(nums[q]>nums[p]){//如果q号元素大于p号元素
                    nums[p+1] = nums[q];//"更新"p+1号元素
                    p++;//前移
                    returnSize++;//记录新数组个数的标记加一
                    q++;//前移
                }else{
                    q++;//如果q号元素没有大于p号元素,只要q前移就好了
                }
            }
            return returnSize;//当q走到数组的结尾时直接返回就可以了
        }
    }
    
    return returnSize;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值