Sliding Window
Time Limit: 12000MS | Memory Limit: 65536K | |
Total Submissions: 35975 | Accepted: 10649 | |
Case Time Limit: 5000MS |
Description
An array of size n ≤ 106 is given to you. There is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves rightwards by one position. Following is an example:
The array is [1 3 -1 -3 5 3 6 7], and k is 3.
The array is [1 3 -1 -3 5 3 6 7], and k is 3.
[1 3 -1] -3 5 3 6 7 | -1 | 3 |
1 [3 -1 -3] 5 3 6 7 | -3 | 3 |
1 3 [-1 -3 5] 3 6 7 | -3 | 5 |
1 3 -1 [-3 5 3] 6 7 | -3 | 5 |
1 3 -1 -3 [5 3 6] 7 | 3 | 6 |
1 3 -1 -3 5 [3 6 7] | 3 | 7 |
Your task is to determine the maximum and minimum values in the sliding window at each position.
Input
The input consists of two lines. The first line contains two integers n and k which are the lengths of the array and the sliding window. There are n integers in the second line.
Output
There are two lines in the output. The first line gives the minimum values in the window at each position, from left to right, respectively. The second line gives the maximum values.
Sample Input
8 3 1 3 -1 -3 5 3 6 7
Sample Output
-1 -3 -3 -3 3 3 3 3 5 5 6 7
题意同上题。
思路:
单调队列。一个单调队列保存非递增序列,一个单调队列维护非递减序列。当滑动一个窗口时就将新元素与最后一个元素比较,后插入队尾。输出的时候输出队头元素,要判断队头元素下标是否符合当前的 l,r 值范围内。
AC:
#include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int MAX = 1000005; int n, k; int num[MAX]; int q_max[MAX], q_min[MAX]; void Max () { int s = 0, e = -1; int l = 1, r = 1 + k - 1; q_max[++e] = 1; for (int i = l; i <= r; ++i) { if(num[i] <= num[q_max[e]]) q_max[++e] = i; else { while(num[i] > num[q_max[e]] && e != s - 1) --e; q_max[++e] = i; } } printf("%d", num[q_max[s]]); for (++l, ++r; r <= n; ++l, ++r) { if (num[r] <= num[q_max[e]]) q_max[++e] = r; else { while(num[r] > num[q_max[e]] && e != s - 1) --e; q_max[++e] = r; } while (q_max[s] > r || q_max[s] < l) ++s; printf(" %d",num[q_max[s]]); } printf("\n"); } void Min () { int s = 0, e = -1; int l = 1, r = 1 + k - 1; q_min[++e] = 1; for (int i = l; i <= r; ++i) { if(num[i] >= num[q_min[e]]) q_min[++e] = i; else { while(num[i] < num[q_min[e]] && e != s - 1) --e; q_min[++e] = i; } } printf("%d", num[q_min[s]]); for (++l, ++r; r <= n; ++l, ++r) { if (num[r] >= num[q_min[e]]) q_min[++e] = r; else { while(num[r] < num[q_min[e]] && e != s - 1) --e; q_min[++e] = r; } while (q_min[s] > r || q_min[s] < l) ++s; printf(" %d",num[q_min[s]]); } printf("\n"); } int main () { while (~scanf("%d%d", &n, &k)) { for (int i = 1; i <= n; ++i) scanf("%d", &num[i]); Min(); Max(); } return 0; }
相关推荐
博客链接 http://blog.csdn.net/CABI_ZGX/article/details/52701138
单调队列优化动态规划广泛应用于解决滑动窗口问题,例如POJ 2823 Sliding Window、P1886 滑动窗口等。这些问题都可以使用单调队列优化动态规划来解决。 实现方法 单调队列优化动态规划的实现方法可以分为以下几步...
我的博客链接:http://blog.csdn.net/CABI_ZGX
- **POJ2823 Sliding Window**:该问题给出一个序列和一个窗口大小k,需要计算在每个位置时,窗口内的最大值或最小值。可以使用单调队列优化将时间复杂度从O(nk)降低至O(n)。 - **最大连续和**:这是一个经典的动态...
这是来自poj的一道关于单调队列的题目。分为max_qu和min_qu两部分来做。
**应用实例**:**POJ2823 SlidingWindow** - **问题描述**:给定一个长度为`N`的数组,一个长度为`K`的滑动窗口从最左端移动到最右端。对于窗口的每种位置,求出窗口覆盖的`K`个数中的最小值和最大值。 - **数据...
- 特殊数据结构,例如单调栈、单调队列等。 - 设计与实现,如Twitter的时间线算法。 8. **算法思维** - 学习算法和刷题的思路指南。 - 具体算法题目的解决思路和策略。 9. **高频面试题** - 如何解决面试中...
8. **滑动窗口最大值(Sliding Window Maximum)**:在数组中找到连续子数组的最大值,可以使用单调栈或双端队列(deque)等数据结构实现。 9. **数据结构优化**:文中提到了利用splay tree(自平衡搜索树)优化...
5. **Sliding Window Maximum**:这是一个滑动窗口最大值问题,要求在不断移动窗口时,找到每个窗口内的最大值。可以使用单调栈或双端队列(deque)来解决。 6. **Factorial Trailing Zeroes**:该问题涉及到数学...