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

如果你写过 26. 删除有序数组中的重复项 这个题,那么这个稍微多了点条件和判定,26题是重复元素保留一个就行了,我们无脑让fast在前面探路,只要和slow指针指向的元素不同,就让把fast放到slow+1这个位置上。然后fast遇到和slow相同的值,就会跳过,最后[0,slow]这个区间是答案,每个值只会出现一次。

这个题让重复元素最多出现两个,那么无非就是加上一个count进行一个计数,然后分类讨论,一种是值不同,那肯定就要加到前面,一种是值相同,但是count数量不超过2,那么也要加到前面。代码如下:

class Solution:
    def removeDuplicates(self, nums: List[int]) -> int:
        slow = 0
        fast = 0
        count = 0
        while fast < len(nums):
            if nums[fast] != nums[slow]:
                slow += 1
                nums[slow] = nums[fast]
            elif slow < fast and count < 2:
                slow += 1
                nums[slow] = nums[fast]
            fast += 1
            count += 1
            if fast < len(nums) and nums[fast] != nums[fast - 1]:
                count = 0
        return slow + 1

这里代码的意思就是,先进行判断,fast的值和slow的值是不是相同,不相同那就要添加进去,相同的话再考虑有没有超过2个,不超过2个就添加进去,超过2个就跳过,然后这里还需要判断slow<fast。因为我们的slow指针指向的有效区间,slow这个值是有效的,假如slow和fast重合,就会存在多添加一个元素的情况了。随后让fast指针后移,然后当前这个数我们添加到有效区间了,count就+1,最后判断下一个元素是不是新元素,是的话就让count清零。

不过这种写法其实感觉还是有点绕的。还有另外一种更简洁的写法,这里的slow代表的是即将写入的位置,不在有效区间,然后我们判断slow-2的位置和fast的位置是不是相同,因为值是连续的,如果相同的话,说明slow-1也是这个值,slow-2也是这个值,已经有两个了,那就不符合条件了,如果不相同,那就添加进去。当然,在0和1的时候n-2会越界,但是我fast<2的话,我们也可以无脑把元素放进去,直接放两个元素不管一样不一样,也不是符合题目条件的,肯定也是没问题的。

class Solution:
    def removeDuplicates(self, nums: List[int]) -> int:
        slow = 0
        fast = 0
        while fast < len(nums):
            if fast < 2 or nums[fast] != nums[slow - 2]:
                nums[slow] = nums[fast]
                slow += 1
            fast += 1
        return slow