单调队列,滑动窗口
题目链接:https://www.acwing.com/problem/content/156/
滑动窗口,维护一个大小为k的队列,使其队列里面的值是单调的。
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class Main {
static BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
static final int N = (int)1e6 + 10;
// 队列中存下标
static int[] q = new int[N];
static int hh = 0, tt = -1;
public static void main(String[] args) throws IOException {
String[] str = bf.readLine().split(" ");
int n = Integer.parseInt(str[0]);
int k = Integer.parseInt(str[1]);
int[] a = new int[n + 1];
String[] str1 = bf.readLine().split(" ");
for(int i = 0 ; i < n; i++) {
a[i] = Integer.parseInt(str1[i]); // 输入
// 当下标 离 i的距离大于 k时,出队
if(i - k + 1 > q[hh])hh++;
// 当a[i] 小于 a[q[tt]] 时, 出队(维护最小的在队首)
while(hh <= tt && a[i] <= a[q[tt]])tt--;
// 入队
q[++tt] = i;
if(i + 1 >= k)bw.write(a[q[hh]] + " ");
}
bw.write("\n");
hh = 0; tt = -1;
for(int i = 0 ; i < n; i++) {
a[i] = Integer.parseInt(str1[i]);
if(i - k + 1 > q[hh])hh++;
// 反之 依然
while(hh <= tt && a[i] >= a[q[tt]])tt--;
q[++tt] = i;
if(i + 1 >= k)bw.write(a[q[hh]] + " ");
}
bw.write("\n");
bw.flush();
}
}
单调栈
栈内元素单调;
题目链接:https://www.acwing.com/problem/content/832/
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Stack;
public class Main {
static BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
public static void main(String[] args) throws Exception {
int n = Integer.valueOf(bf.readLine());
String[] str = bf.readLine().split(" ");
int[] a = new int[n];
Stack<Integer> stack = new Stack<Integer>();
for(int i = 0; i < n; i++) a[i] = Integer.valueOf(str[i]);
for(int i = 0; i < n; i++) {
// int ans = -1; 如果栈内 从底 到 Top是 从大到小的,保证每次peek都是最大的
while(!stack.isEmpty() && stack.peek() >= a[i]) {
stack.pop();
}
if(stack.isEmpty())bw.write("-1 ");
else bw.write(Integer.valueOf(stack.peek()).toString() + " ");
stack.push(a[i]);
}
bw.flush();
}
}