【Leetcode】80.删除有序数组中的重复项 II

image.png

这一题跟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即可。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容