#dDDLDPybttg050501. 1597:【 例 1】滑动窗口
1597:【 例 1】滑动窗口
好的,我将这道题整理为清晰的题面格式,并补充样例解释、数据范围与时空限制:
题目描述
原题来自:POJ 2823
给定一个长度为 的数组 ,一个长度为 的滑动窗口从数组最左端移动到最右端。你只能看到窗口中的 个数,每次窗口向右移动一位。
请找出窗口在每个位置时的最大值和最小值。
输入格式
第一行两个整数 和 ;
第二行 个整数,表示数组的 个元素(值在 范围内)。
输出格式
第一行输出滑动窗口从左向右移动到每个位置时的最小值,共 个数,每个数之间用一个空格分开;
第二行输出滑动窗口从左向右移动到每个位置时的最大值,共 个数,每个数之间用一个空格分开。
样例
样例输入
8 3
1 3 -1 -3 5 3 6 7
样例输出
-1 -3 -3 -3 3 3
3 3 5 5 6 7
样例解释
数组:,。
窗口位置及各位置的最小值、最大值:
| 窗口 | 最小值 | 最大值 |
|---|---|---|
| [1 3 -1] -3 5 3 6 7 | -1 | 3 |
| 1 [3 -1 -3] 5 3 6 7 | -3 | |
| 1 3 [-1 -3 5] 3 6 7 | 5 | |
| 1 3 -1 [-3 5 3] 6 7 | ||
| 1 3 -1 -3 [5 3 6] 7 | 3 | 6 |
| 1 3 -1 -3 5 [3 6 7] | 7 |
因此:
- 最小值序列:
- 最大值序列:
数据范围
- 对于 的数据,;
- 对于 的数据,;
- 对于 的数据,。
时空限制
- 时间:
- 内存:
提示
此题是经典的 滑动窗口最值 问题,可以用 单调队列 在线性时间内解决。
方法:
- 最小值:维护一个单调递增的双端队列,队列中存储数组下标。保证队首元素是当前窗口的最小值。
- 当队首下标超出窗口范围时,弹出队首;
- 当新元素 入队时,从队尾开始弹出所有大于等于 的元素(因为它们在窗口内不可能成为最小值),然后将 入队;
- 当窗口形成时(),队首元素即为当前窗口最小值。
- 最大值:类似,维护一个单调递减的双端队列,保证队首元素是当前窗口的最大值。
步骤:
- 先处理最小值:
- 遍历 从 到 :
- 如果队首下标 ,则弹出队首;
- 从队尾弹出所有 的下标;
- 将 入队;
- 若 ,输出 。
- 遍历 从 到 :
- 同理处理最大值(弹出条件改为 )。
复杂度:每个元素入队出队一次,。
注意: 最大 ,输入输出要用较快的 IO 方式(如 scanf/printf 或关闭同步的 cin/cout)。