双指针算法以及滑动窗口Python(及其相关题目)(待更新)

1. 双指针基础知识

1. 双指针简介

双指针(Two Pointers):在遍历元素的过程中,不是使用单个指针进行访问,而是使用两个指针进行访问,从而达到相应的目的. 如果两个指针方向相反,为对撞指针, 如果指针方向相同,称为快慢指针.如果两个指针分别属于不同的数组/链表,称为分离双指针
时间复杂度从O(n**2)降到了O(n)

2. 对撞指针

  1. 定义:对撞指针:两个指针left,right分别指向第一个元素和最后一个元素,然后left指针不断递增,right不断递减,直到两个指针相撞或达到其他条件为止
  2. 步骤:
    1. 使用两个指针left,right分别指向第一个元素和最后一个元素
    2. 在循环体中将左右指针相向移动,当满足一定条件时,将左指针右移(+1);当满足一些条件时,将右指针左移(-1)
    3. 直到两指针相撞或满足其他特殊条件时,跳出循环体
  3. 适用范围(有序数组或字符串问题):
    1. 查找有序数组中满足某些约束条件的一组元素问题:比如二分查找、数字之和等问题
    2. 字符串反转问题:反转字符串、回文数、颠倒二进制等问题
  4. 伪代码:
left = 0
right = len(nums) - 1

while left < right:
	if 满足要求的特殊条件:
		return 符合条件的值
	elif 一定条件1:
		left += 1
	elif 一定条件2:
		right -= 1
return 没找到

3. 快慢指针

  1. 定义:两个指针从同一侧开始遍历序列,且移动的步长一个快一个慢。移动快的指针被称为快指针(fast),移动慢的指针被称为慢指针(slow)。两个指针以不同速度、不同策略移动,直到快指针移动到数组尾端,或者两指针相交,或者满足其他特殊条件时为止。
  2. 步骤:
    1. 使用两个指针slow和fast.slow一般指向序列的第一个元素(slow = 0), fast一般指向序列的第二个元素(fast = 1)
    2. 在循环体中将快慢指针向右移动.当满足一定条件时,将慢指针右移(+1), 当满足另一些条件时,将快指针右移(+1)
    3. 到快指针移动到数组尾端(即 fast == len(nums) - 1),或者两指针相交,或者满足其他特殊条件时跳出循环体
  3. 适用范围:一般用于处理数组中的移动、删除元素问题,或者链表中的判断是否有环、长度问题
  4. 伪代码:
slow = 0
fast = 1
while 没有遍历完:
	if 满足一些条件:
		slow += 1
	fast += 1
return ans

4. 分离双指针

  1. 定义:两个指针分别属于不同的数组 / 链表,两个指针分别在两个数组 / 链表中移动。
  2. 步骤:
    1. 使用两个指针left_1, left_2.left_1指向第一个数组的第一个元素(left_1 = 0),left_2指向第二个数组的第二个元素(left_2 = 0)
    2. 当满足一些条件时,两个指针同时右移(left_1 += 1, left_2 += 1)
    3. 当满足另外一些条件是,left_1右移(left_1 += 1)
    4. 当满足其它一些条件时,left_2右移(left_2 += 1)
    5. 当其中一个数组遍历完或一些其他条件时跳出循环
  3. 适用范围:一般用于处理有序数组合并,求交集、并集问题
  4. 伪代码:
left_1 = 0
left_2 = 0
while left_1 < len(nums1) and left_2 < len(nums2):
    if 一定条件 1:
        left_1 += 1
        left_2 += 2
    elif 一定条件 2:
        left_1 += 1
    elif 一定条件 3:
        left_2 += 1

2. 滑动窗口

2.1 算法介绍

  1. 滑动窗口(Sliding Window):在给定数组 / 字符串上维护一个固定长度或不定长度的窗口。可以对窗口进行滑动操作、缩放操作,以及维护最优解操作。
  2. 操作:
    1. 滑动操作:窗口可按照一定方向进行移动。最常见的是向右侧移动
    2. 缩放操作:对于不定长度的窗口,可以从左侧缩小窗口长度,也可以从右侧增大窗口长度。
  3. 利用了快慢指针的技巧

2.2 适用范围:

  1. 一般用来解决一些查找满足一定条件的连续区间的性质(长度等)的问题
  2. 种类:
    1. 固定长度窗口
    2. 不定长度窗口
      1. 求解最大的满足条件的窗口
      2. 求解最小的满足条件的窗口

2.3 固定长度窗口

  1. 步骤:
    假定窗口的固定大小为window_size
    1. 使用两个指针 left、right。初始时,left 、right 都指向序列的第一个元素,即:left = 0,right = 0 ,区间 [left, right] 被称为一个窗口
    2. 当窗口未达到 window_size 大小时,不断移动 right,先将 window_size 个元素填入窗口中。
    3. 当窗口达到 window_size 大小时,判断窗口内的连续元素是否满足题目限定的条件
      1. 如果满足,再根据要求更新最优解。
      2. 然后向右移动 left,从而缩小窗口长度,即 left += 1,使得窗口大小始终保持为 window_size。
    4. 向右移动 right,将元素填入窗口中
    5. 重复 2 ~ 4 步,直到 right 到达序列末尾
  2. 伪代码实现:
left = 0
right = 0

while right < len(nums):
	window.append(nums[right])
	
	if right - left + 1 >= window_size:
		window.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值