双指针法分为滑动窗口、左右指针、快慢指针、首尾指针三种。
滑动窗口 | 左右指针 | 快慢指针 | 首尾指针 | |
---|---|---|---|---|
left和right的初始化和更新 | left用数字初始和更新,right用循环初始和更新 | left用数字初始和更新,right用循环初始和更新 | slow、fast从起点出发,但速度一慢一快,如果有循环结构,则快指针一定会追上慢指针 | left和right分别从首、尾向中间移动 |
left和right的作用 | left和right用于记录窗口的左右边缘 | left用于更新记录,right用于遍历 | 两者相交表示有循环结构 | left和right用于更新左右两端的数字 |
解决问题 | 子串、子数组问题 | 遍历中的更新记录问题 | 判断是否存在循环结构 | 有序数组中的查找两个数,时间复杂度O(n)优于二分查找O(nlogn);无序数组找最佳边界 |
左右指针
- 适用问题:列表、字符串原地按要求删除、移动、更新元素
- 一个指针指向要替换的位置,一个指针遍历
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
# i指向要替换的位置(下一个应该被填充的位置),j用于遍历
# j没有遇到val就写到i的位置,遇到就i不动j向前
slow,fast=0,0
while fast<=len(nums)-1:
if nums[fast]!=val:
nums[slow]=nums[fast]
slow+=1
fast+=1
return slow
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
# left负责记录结果,right负责遍历
# 保留不重复的结果
left=1
for right in range(1,len(nums)):
if nums[right]!=nums[right-1]:
nums[left]=nums[right]
left+=1
return left
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
j=0
for i in range(len(nums)):
if nums[i]!=0:
nums[j],nums[i]=nums[i],nums[j]
j+=1
return nums
class Solution:
def backspaceCompare(self, s: str, t: str) -> bool:
def tran_word(s):
s=list(s)
left,right=0,0
for right in range(len(s)):
if s[right]!='#':
s[left]=s[right]
left+=1
elif s[right]=='#' and left>0:
left-=1
# 如果遇到#且left已经到达最左端,就继续遍历
return ''.join(s[:left])
return tran_word(s)==tran_word(t)
class Solution:
def backspaceCompare(self, s: str, t: str) -> bool:
def tran_word(s):
s=list(s)
left,right=0,0
for right in range(len(s)):
if s[right]!='#':
s[left]=s[right]
left+=1
elif s[right]=='#' and left>0:
left-=1
# 如果遇到#且left已经到达最左端,就继续遍历
return ''.join(s[:left])
return tran_word(s)==tran_word(t)
344.反转字符串
剑指Offer 05.替换空格
151.翻转字符串里的单词(综合题)
206.反转链表
19.删除链表的倒数第N个节点
快慢指针
面试题 02.07. 链表相交
142.环形链表II
首尾指针
- 两个指针从首尾开始遍历
344.反转字符串
第15题. 三数之和
第18题. 四数之和
一、适用问题
连续子串、连续子数组
二、类型
- 固定长度的窗口,用if
- 可变长度的窗口,用while
三、思路
01- 初始化维护变量、非维护变量、左右窗口
02-移动right,更新维护变量
03- right不动,更新left,更新维护变量
04-输出结果
三、常见问题
a. 输出结果的位置
b. 两端最大<>中间连续最小【Day1]
c. 窗口起标记作用,输出结果用到了这个标记【Day6】