单调栈和单调队列

单调栈:

用于解决求出距离当前值最近的满足某个性质的值

 1 给定一个长度为N的整数数列,输出每个数左边第一个比它小的数,如果不存在则输出-1 2 
 3 输入格式
 4 第一行包含整数N,表示数列长度。
 5 
 6 第二行包含N个整数,表示整数数列。
 7 
 8 输出格式
 9 共一行,包含N个整数,其中第i个数表示第i个数的左边第一个比它小的数,如果不存在则输出-110 
11 数据范围
12 1≤N≤105
13 1≤数列中元素≤109
14 输入样例:
15 5
16 3 4 2 7 5
17 输出样例:
18 -1 3 -1 2 2
19 
20 
21 ########################
22 
23 #include <iostream>
24 
25 using namespace std;
26 
27 const int N = 1e5+10;
28 
29 int arr[N];
30 int stk[N], top = -1;
31 
32 int main(){
33     int n;
34     cin >> n;
35     for(int i = 0;i < n;++i){
36         cin >> arr[i];
37     }
38     for(int i = 0;i < n;++i){
39         //stack存下标和值都可以
40         while(top >= 0 && stk[top] >= arr[i])--top;
41         if(top >= 0)printf("%d ",stk[top]);
42         else printf("-1 ");
43         stk[++top] = arr[i];
44     }
45     return 0;
46 }
View Code

单调队列:

 用于解决当前窗口中的最值也可以说是满足条件的唯一解

 1 给定一个大小为n≤106的数组。
 2 
 3 有一个大小为k的滑动窗口,它从数组的最左边移动到最右边。
 4 
 5 您只能在窗口中看到k个数字。
 6 
 7 每次滑动窗口向右移动一个位置。
 8 
 9 以下是一个例子:
10 
11 该数组为[1 3 -1 -3 5 3 6 7],k为3。
12 
13 窗口位置    最小值    最大值
14 [1 3 -1] -3 5 3 6 7    -1    3
15 1 [3 -1 -3] 5 3 6 7    -3    3
16 1 3 [-1 -3 5] 3 6 7    -3    5
17 1 3 -1 [-3 5 3] 6 7    -3    5
18 1 3 -1 -3 [5 3 6] 7    3    6
19 1 3 -1 -3 5 [3 6 7]    3    7
20 您的任务是确定滑动窗口位于每个位置时,窗口中的最大值和最小值。
21 
22 输入格式
23 输入包含两行。
24 
25 第一行包含两个整数n和k,分别代表数组长度和滑动窗口的长度。
26 
27 第二行有n个整数,代表数组的具体数值。
28 
29 同行数据之间用空格隔开。
30 
31 输出格式
32 输出包含两个。
33 
34 第一行输出,从左至右,每个位置滑动窗口中的最小值。
35 
36 第二行输出,从左至右,每个位置滑动窗口中的最大值。
37 
38 输入样例:
39 8 3
40 1 3 -1 -3 5 3 6 7
41 输出样例:
42 -1 -3 -3 -3 3 3
43 3 3 5 5 6 7
44 
45 ##########################
46 
47 #include <iostream>
48 
49 using namespace std;
50 
51 const int N = 1e6+10;
52 
53 int arr[N];
54 int q[N];
55 int head = 0, tail = -1;
56 
57 int main(){
58     int n, k;
59     cin >> n >> k;
60     for(int i = 0;i < n;++i) cin >> arr[i];
61     for(int i = 0;i < n;++i){
62         while(head <= tail && i - q[head] + 1 > k)++head;
63         while(head <= tail && arr[i] <= arr[q[tail]])--tail;
64         q[++tail] = i;
65         if(i >= k-1)printf("%d ",arr[q[head]]);
66     }
67     cout << endl;
68     head = 0, tail = -1;
69     for(int i = 0;i < n;++i){
70         while(head <= tail && i - q[head] + 1 > k)++head;
71         while(head <= tail && arr[i] >= arr[q[tail]])--tail;
72         q[++tail] = i;
73         if(i >= k-1)printf("%d ",arr[q[head]]);
74     }
75     return 0;
76 }
View Code

end

原文地址:https://www.cnblogs.com/sxq-study/p/12083093.html