單調隊列,滑動窗口
題目鏈接: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();
}
}