个人理解:快慢指针关键在于:快指针是要把找到什么样的数,符合什么样的性质,给到慢指针,写在这一层判断中去。快指针每次都会动,慢指针只有在快指针找到符合要求的给慢指针的数的时候再动。**在数组中并没有真正意义上的指针,但我们可以把索引当做数组中的指针,这样也可以在数组中施展双指针技巧,本文主要讲数组相关的双指针算法。
数组问题中比较常见的快慢指针技巧,是让你原地修改数组,这是数字题目运用快慢指针技巧的题眼特征。而所谓快慢指针,就是两个指针同向而行,一快一慢。
leetcode26 删除有序数组中的重复项
思路:我们让慢指针 slow
走在后面,快指针 fast
走在前面探路,找到一个不重复的元素就赋值给 slow
并让 slow
前进一步。
这样,就保证了 nums[0..slow]
都是无重复的元素,当 fast
指针遍历完整个数组 nums
后,nums[0..slow]
就是整个数组去重之后的结果。
由于要对比,所以一开始就把fast设为1
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
slow = 0
fast = 1
l = len(nums)
while fast < l:
if nums[slow] != nums[fast]:
slow += 1
nums[slow] = nums[fast]
# 维护 nums[0..slow] 无重复
fast += 1
return slow + 1# 数组长度为索引 + 1
leetcode 27 移除元素
在这一道题目中,快指针找的要给慢指针的数就是不重复元素,这样到slow的数都是无重复的
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
slow,fast = 0, 0
while fast < len(nums):
if nums[fast] != val:
nums[slow] = nums[fast]
slow += 1
fast += 1
return slow #这种细节地方还要再考虑,放了一个元素slow 再加的1
#在这里快指针要找的给慢指针的数就是所有不等于val的数字,这样前slow个数字每个都不等于val
leetcode 283 移动零
在这一题目中,快指针找到的要给慢指针的数是找到的非零数都给他
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
#这道题典型的快慢指针,题目要求是原地操作
slow,fast = 0, 0
while fast < len(nums):
if nums[fast] != 0:
nums[slow] =nums[fast] #先赋值再slow++
slow += 1
fast += 1
for i in range(slow,len(nums)):
nums[i] = 0
切片和索引是两种不同的数据访问方式。切片用于访问序列的一部分,python中不可以用数组索引来赋值,例如nums[a,b] = 0
这段代码是编译不能通过的
后面两种方法的实现细节
注意这里和有序数组去重的解法有一个细节差异,我们这里是先给 nums[slow]
赋值然后再给 slow++
,这样可以保证 nums[0..slow-1]
是不包含值为 val
的元素的,最后的结果数组长度就是 slow
。