题目大意:原地去除排序数组中的重复项,但是要将重复的数保留两个,这是本题的特殊之处。
题目分析:本题因为只能使用O(1)的额外空间,所以不能另外再开辟一个数组,只能在原地操作。本题可以在O(n)的时间复杂度内解决。思路:用times表示当前数字重复的次数,用move表示当前数字需要向前移动的步数,用validStep表示有效的数位。我们只要从前往后扫描,计算出每个数字需要往前移动几格就行了。如果当前的数字与前一个数字相等,则times加1,同时向前移动move步。若不相等,times=1重新开始计数。前移的话,分为两种情况。一是紧接着几个重复的数之后的第一个不同的数,比如说1,1,1,2,3,3,4中的2和4。他们移动的步数首先是times-2步,2只需要移动1步,其次还要加上move步。二是第二个重复的数,例如1,1,1,2,3,3,4中的第二个1和第二个3,他们只需要移动move步。而move的值是根据前面数字里重复出现的个数累加的。
代码展示:
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
if(nums.size()==0)
return 0;
if(nums.size()==1)
return 1;
int times = 1;
int move = 0;
int validStep = 1;
for(int i=1;i<nums.size();i++){
if(nums[i]==nums[i-1]){
times += 1;
if(times==2){
nums[i-move] = nums[i];
validStep = i-move+1;
}
}
else{
if(times==1){
nums[i-move] = nums[i];
validStep = i-move+1;
}
else if(times-2+move>=0){
nums[i-times+2-move] = nums[i];
validStep = i-times+2-move+1;
move += times-2;
}
times = 1;
}
}
return validStep;
}
};