题目
给你一个有序数组 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,果然还是要努力呜呜!