LeetCode百题刷001双指针·快慢指针
遇到的问题都有解决的方案,希望我的博客可以为你提供一些帮助
图片源自leetcode
题目:80. 删除有序数组中的重复项 II - 力扣(LeetCode)
这一题是经典的双指针问题,题目要求在给定数组上原地修改且空间复杂度需要为。
一、算法思路
核心思想:利用 双指针 技术,通过一个快指针i扫描数组,一个慢指针k标记有效部分的末尾+1的元素位置由于数组下标从0开始返回的k值就是有效元素的个数。
关键观察:
- 由于数组已排序,重复元素必然连续出现。
- 只需确保 每个元素最多保留两次,即当发现一个新元素时,直接保留;若当前元素与慢指针前两个位置的元素相同,说明已经保留过两次(因为所给的数组是有序的,且相同的元素最多可保留2个,每次的k-2所指向的其实是上一个保留的元素),跳过它。
二、详细步骤
边界处理:
- 如果数组长度 ≤ 2,直接返回原长度(无需处理)。
初始化指针:
- 慢指针
k = 2
,因为前两个元素无论是否重复,都可以直接保留。
遍历数组:
- 快指针
i
从索引 2 开始遍历整个数组。 - 对每个元素
nums[i]
,检查它是否与nums[k-2]
相同
如果不同:说明 nums[i]
可以保留,将其复制到 nums[k]
,然后 k += 1
。
如果相同:说明已经保留过两次,跳过当前元素。
终止条件:遍历完成后,k
即为新数组的长度。
class Solution:def removeDuplicates(self, nums: list[int]) -> int:if len(nums)<=2:return len(nums)else:k=2for i in range (2,len(nums)):if nums[i]==nums[k-2]:#该元素保留过两次,不保留continueelse :#新元素,保留nums[k]=nums[i]k+=1return k
结果:
三、复杂度分析
主要耗时在for循环,快指针遍历数组一次,最坏情况下需要“保留”n-2次,时间复杂度