单调栈:
用于解决求出距离当前值最近的满足某个性质的值
1 给定一个长度为N的整数数列,输出每个数左边第一个比它小的数,如果不存在则输出-1。 2 3 输入格式 4 第一行包含整数N,表示数列长度。 5 6 第二行包含N个整数,表示整数数列。 7 8 输出格式 9 共一行,包含N个整数,其中第i个数表示第i个数的左边第一个比它小的数,如果不存在则输出-1。 10 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 }
单调队列:
用于解决当前窗口中的最值也可以说是满足条件的唯一解
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 }
end