学习双指针的应用
算法
- 我们使用了两个指针, i i i 是遍历指针,指向当前遍历的元素; j j j 指向下一个要覆盖元素的位置。
- 同样,我们用 c o u n t count count 记录当前数字出现的次数。 c o u n t count count 的最小计数始终为 1。 我们从索引 1 开始一次处理一个数组元素。
- 若
i
i
i指向的元素与
j
j
j指向的元素相同,即
nums[i]==nums[j]
,则 c o u n t + 1 count+1 count+1。 - 若 c o u n t > 2 count > 2 count>2,则说明遇到了多余的重复项。在这种情况下,我们只向前移动 i i i,而 j j j 不动。
- 若 c o u n t < = 2 count <=2 count<=2,则我们将 i 所指向的元素移动到 j 位置,并同时增加 i 和 j。
- 若
i
i
i指向的元素与
j
j
j指向的元素不相同,即
nums[i] != nums[j]
,说明遇到了新元素,则我们更新 c o u n t = 1 count = 1 count=1,并且将该元素移动到 j j j 位置,并同时增加 i i i 和 j j j。 当数组遍历完成,则返回 j j j。
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
j = 0 # slow
count = 1 # 当前这个数出现的次数,第一个数就是出现了一次
for i in range(1, len(nums)):
if nums[i] == nums[j]:
count += 1
if count <= 2:
j += 1
nums[j] = nums[i]
else:
# 从1开始计数
count = 1
j += 1
nums[j] = nums[i]
return j+1
复杂度分析
- 时间复杂度: O ( N ) O(N) O(N),我们遍历每个数组元素一次。
- 空间复杂度: O ( 1 ) O(1) O(1)。