6.滑动窗口 单调队列

 

 

 暴力做法每次需要遍历一下窗口内的每一个数

时间复杂度O(n * k)

找性质

 先看区间内的最小值

-3比3存活的时间更久,且-3比3小,所以-3是更优解,只要-3存在,3就不会是答案

tt 表示当前这个队列存储所用到位置

q[tt]存储的是数组中元素的下标

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N = 1000010;
 4 int a[N], q[N];
 5 //a是原来的值,q是队列
 6 //队列里面存的是下标
 7 int main() {
 8     int n, k;
 9     cin >> n >> k;
10     for (int i = 0; i < n; i++) {
11         cin >> a[i];
12     }
13     int hh = 0, tt = -1;
14     for (int i = 0; i < n; i++) {
15         //判断队头是否已经滑出窗口 
16         if (hh <= tt && i - k + 1 > q[hh]) { 
17             hh++;
18         }
19         while (hh <= tt && a[q[tt]] >= a[i]) {
20             tt--;
21         }
22         q[++tt] = i;
23         if (i >= k - 1) {
24             cout << a[q[hh]] << " ";
25         }
26     }
27     cout << endl;
28     hh = 0, tt = -1;
29     for (int i = 0; i < n; i++) {
30         if (hh <= tt && i - k + 1 > q[hh]) {
31             hh++;
32         } 
33         while (hh <= tt && a[q[tt]] <= a[i]) {
34             tt--;
35         }
36         q[++tt] = i;
37         if (i >= k - 1) {
38             cout << a[q[hh]] << " ";
39         }
40     }
41     cout << endl;
42     return 0;
43 }
原文地址:https://www.cnblogs.com/fx1998/p/13285925.html