核心思想:使用两个指针lr表示窗口的左右边界。r表示即将入窗口的元素,l表示即将出窗口的元素。这种出和入只发生在窗口特定的位置,与队列相似。

1. 定长滑动窗口

只用r即可,l=r-w+1

模板:

1
2
3
4
5
6
7
8
9
10
11
12
for r in (0..n-1); do
// enter (loop i)
arr[r] enters the window
l = r - w + 1
if l < 0; then
continue
fi
// update (loop i)
update window state
// exit, prepare for the next loop (for loop i+1)
l++
done

注意:出窗口的操作要在更新窗口状态之后。这样,当r指代的元素入窗口时,由r推出的l所指代的元素会在下一轮循环开始之前出窗口。相应的,在下一轮循环i+1时,上一个r推出的l所指代的元素在i+1之前就出了窗口。确保状态更新时i+1的出入都发生过了

2. 变长滑动窗口

需要lr两个指针。r表示所有即将入窗口的元素,l表示被淘汰的、即将出窗口的元素。

1
2
3
4
5
6
7
8
9
10
11
12
l := 0
for r in (0..n-1); do
// enter (loop i)
arr[r] enters the window
// need someone to exit? (loop i)
if [check_exit]; then
delete arr[l] from window state
l++
fi
// update (loop i)
update window state
done

3. 例题