采用双指针 (似乎要求扫描一遍的方法大多可以采用双指针解决)
要明确一点,k指针所指位置的数值没有任何意义,因为既然它已经被k指针指向了,说明这就是一个“不合法”的位置,最终只能被替换
需要比较数值的是i与i的前一位数,分为“合法”和“不合法”两种情况。“合法”情况中又存在着两种情况:
1、两数相同,count<2 2、两数不同 如果遇到的是合法情况,那么直接将i的值赋值给k(之前使用的是交换操作,把数字移到数组末端,但仔细想想似乎没有这个必要)
“不合法”的情况只有一种:两数相同,count = 2 如果遇到的是不合法情况,那么k所指向的位置不变,i正常++
注意点:
1、 i和k从1开始,因为第0位的数字肯定是合法的,且count初始化为1,如果从第0个数开始,就会造成后面的逻辑混乱
2、 只要覆盖,不需要交换
3、 只有两个数的时候,该数组一定是合法的,做一个特殊情况判断,直接返回原数组
时间复杂度:O(n)
空间复杂度:O(1)
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
int i = 1, k = 1;
int count = 1;
if (nums.size() <= 2)
return nums.size();
for(; i < nums.size(); i++){
if(nums[i] == nums[i-1]){
if(count < 2){
nums[k++] = nums[i];
count++;
}
}
else {
count = 1;
nums[k++] = nums[i];
}
}
return k;
}
};