这一题跟leetcode-26题一样
只不过26题只是允许出现一次,这题是允许出现两次
思路差不多,也是需要快慢指针来记录
slow指针指向当前符合条件的最后一个元素
fast指向遍历的当前元素
因为允许两个重复的元素存在,所以需要一个计数器cnt来记录当前重复元素的个数
class Solution {
public int removeDuplicates(int[] nums) {
if(nums.length < 2)
return nums.length;
int slow = 0;
int last = nums[0];
int cnt = 0;
for(int i = 0; i < nums.length; ++i){
if(last == nums[i]){
if(cnt < 2){
cnt++;
nums[slow++] = nums[i];
}
}else{
last = nums[i];
nums[slow++] = nums[i];
cnt = 1;
}
}
return slow;
}
}
代码也比较简单
首先判断当前元素,也就是fast指针指向的元素(在题目中为for循环中的i指向的)是否与之前记录的最后一个元素相等
如果相等的话,再判断当前的计数器的个数是否小于2,小于2则更新slow指针的元素
如果不相等的话,那么就是一个新元素,那么更新cnt=1,last元素为当前元素,且更新slow指针所指向的元素。
对比下官方的solution
我自己的解法还是有点拙劣,用上了计数器,代码也显得比较啰嗦
下面放上官方的解法
class Solution {
public int removeDuplicates(int[] nums) {
int len = nums.length;
if(len < 2){
return len;
}
int slow = 2, fast = 2;
while(fast < len){
if(nums[slow - 2] != nums[fast]){
nums[slow++] = nums[fast];
}
fast++;
}
return slow;
}
}
分析代码:
首先只有2个或者2个一下的元素的时候,直接进行返回即可。
前两个元素是肯定满足条件的,所以直接从第三个元素开始进行遍历判断即可
slow指向的是当前满足条件的最后一个元素的下一个元素,那么slow-2则表示的是满足条件的倒数第二个元素,那么当fast指向的数字对比slow-2所指向的元素时
若nums[slow - 2] == nums[fast],则表示 fast slow-1 slow-2,这三个所指向的元素都相等,那么则不满足条件,此时fast前进即可,再进行下一轮比较。
若nums[slow - 2] != nums[fast],则表示fast指向的可能与slow-1相等或者不等,这都是满足条件的,此时更新slow即可。同时也要更新fast(fast在每一轮中都要进行更新)
对于以上这种题型,可以总结一个通用的套路,即数组里面需要留n个相同的数字的时候,改写上面的2即可。