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

题目

给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。

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

1.使用普通计数双指针(代码运行时间较长)

一开始做完上一道题想的是使用双指针,思路为用一个变量计数如果重复两次则终止计数进行下一循环。后面发现自己的代码会在示例2出现的结果为[0,0,1,1,2,3,3,3]

结果多出来一个3,我通过看代码发现,语句多重复了一次,于是我在结果多添了一句话,实现了在运行过程中成功,但是卡在了[1,1]的输入上。之后又多次修改代码有不过的情况就把该情况列为特殊进行修改,最后多次阅读代码后发现自己卡在一个很简单的点上,关于p1指针上,最终进行修改运行成功,思路和代码如下。

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
    int p1=0,p2=0,a=0,k=0;
    int length=nums.size();
    length--;
    cout<<"la="<<length;
    for(;p2<=length;p2++)
        {

            int i=0;
           for(a=p2;a<=length;a++)
           {
            if(nums[a]==nums[p2]&&i<=1)
            {
                nums[k++]=nums[p2];
                cout<<"p2="<<nums[a];
                cout<<"k="<<k<<" ";
                i++;
            }
            if(i>1)
            {cout<<"跳出"<<" ";
                break;
            }

           }
            if(i>1)
            {
                for(p1=p2;p1<=length;p1++)
                {
                    if(nums[p1]!=nums[p2])
                    {
                        p2=p1-1;
                        cout<<p2<<" ";
                        break;
                    }
                }
            }
            if(p1>length)//进行判断,如果p1遍历到最后一位都没有找到不相同元素则说明数组以排序完成,因为一开始已经将相同元素放入数组中,所以可以break。一直缝缝补补代码出现错误,一开始没有意识到p1指针也可以利用判断问题TVT。
            {
                break;
            }
    }
    cout<<"l="<<length;
    cout<<k;
    return k;

    }
};

2.双指针(快慢指针法)

力扣官方题解的方法,采用两个指针,一个为slow指针一个为fast指针,由于重复次数为两次,所以数组的前两位可以不计,所以将数组的初值设为2,之后则可以将slow的指针固定位置将fast指针所指元素进行比较,可得出结果。觉得这个算法是一个蛮有意思的算法,其中个人认为思路可以着重在是重复2次,并且为有序数组,故可以尝试利用2和双指针得出。

代码如下:

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

这个代码运行的时间就减少了很多TvT,果然还是要努力呜呜!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值