滑动窗口算法是一种基于双指针技巧的高效算法, 常用于解决数组或字符串上的一些特定问题.
算法讲解
基本概念
滑动窗口算法可以想象成在一个数组或字符串上有一个固定大小或者可变大小的窗口, 该窗口在数组或字符串上从左到右滑动. 在滑动的过程中, 根据具体问题的要求, 对窗口内的元素进行计算和操作. 窗口的大小可以根据问题的不同而变化, 有时是固定的, 有时是动态调整的.
算法实现步骤
- 初始化: 定义两个指针(例如
left
和right
), 表示窗口的左右边界, 初始时通常都指向数组或字符串的起始位置. 同时, 根据问题的需要, 初始化一些变量来记录窗口内的状态, 如窗口内元素的和, 不同元素的个数等. - 移动右指针: 将右指针向右移动一位, 扩大窗口的范围, 把新元素纳入窗口内. 然后根据问题的要求, 更新窗口内的状态变量.
- 判断和调整: 检查当前窗口是否满足问题的条件. 如果不满足条件, 就需要移动左指针, 缩小窗口的范围, 同时更新状态变量, 直到窗口满足条件为止.
- 重复步骤: 不断重复步骤 2 和步骤 3, 直到右指针到达数组或字符串的末尾. 在这个过程中, 根据问题的具体要求, 记录和更新所需的结果.
例题: 无重复字符的最长子串
这是 Leetcode 上面的一道题目: 3. 无重复字符的最长子串.
给定一个字符串s
,请你找出其中不含有重复字符的最长子串的长度。
例如:
s = "abcabcbb"
, 最长子串长度为 3s = "bbbbb"
, 最长子串为 1s = "pwwkew"
, 最长子串长度为 3
解题思路
使用一个滑动窗口, 左边界为l
, 右边届为r
, 滑动窗口为[l, r]
(需要注意是闭区间, 即包含右端点r
处的元素). 窗口内的元素是没有重复的, 这是本程序的循环不变量.
- 初始值为
l=0
,r=0
. 此时包含一个元素, 窗口状态满足循环不变量. - 首先对