80. 删除排序数组中的重复项 II
给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。
示例 1:
给定 nums = [1,1,1,2,2,3],
函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2, 3 。
你不需要考虑数组中超出新长度后面的元素。
示例 2:
给定 nums = [0,0,1,1,1,1,2,3,3],
函数应返回新长度 length = 7, 并且原数组的前五个元素被修改为 0, 0, 1, 1, 2, 3, 3 。
你不需要考虑数组中超出新长度后面的元素。
这道题和之前的26. 删除排序数组中的重复项唯一的区别就是这到题可以保留两个重复的数字,承接上一题的做法,这里我们只需要在两者相同的时候增加一个计数的功能就可以了。
这里有两个需要注意的地方:
- 计数是连续相等的时候才会cnt增加计数,只要不相等的时候,计数器就会清零。
- 在两者相等的情况下,计数器和需要写入的位置 i 都要自增加一。写入位置 i 在计数器没达到限制的时候就增加,但是计数器达到限制的时候,需要回退一位。因为后面一个相同的数字不能再算进来了。
- 在计数器增加的时候,需要对 i 位置进行赋值操作。两者相等的情况下,还未到限制个数: i 右移一位,对其赋值。如果到达了限制个数,i 就在加一位的基础上退一位,回到原位置,计数器减一,再对之后数的进行对比判断。
- 上面计数器在达到限制之后减一的原因是:如果是多个连续的重复数字,当前达到限制值之后我们将cnt计数置0的话,之后连续重复的数字又是从头开始计数,这样就会出错,所以这里只减一,当两个数对比不相等的时候,我们才将计数器清零。
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
i = 0
cnt = 0
n = len(nums)
for j in range(1, n):#对之后的数字遍历
if nums[j] != nums[i]:#两者不相等的情况下,对 i+1赋值 j,两者的下标都右移
i += 1
nums[i] = nums[j]
cnt = 0
else:#两者相等的情况下
cnt += 1
i += 1#计数器和 i 要增加一
nums[i] = nums[j]#同时对齐进行赋值
if cnt == 2:#到达限制,计数器减一,因为
cnt -= 1
i -= 1
return i+1