单调栈
给定一个长度为 N 的整数数列,输出每个数左边第一个比它小的数,如果不存在则输出 −1。
输入格式
第一行包含整数 N,表示数列长度。
第二行包含 N 个整数,表示整数数列。
输出格式
共一行,包含 N 个整数,其中第 i 个数表示第 i 个数的左边第一个比它小的数,如果不存在则输出 −1。
数据范围
1≤N≤10510^5105
1≤数列中元素≤10910^9109
输入样例:
5
3 4 2 7 5
输出样例:
-1 3 -1 2 2
思路分析
如果按照最朴素的想法做的话,找第i个数之前第一个小于这个数的数,无非就是从i - 1位置向前循环,输出遇见的第一个小于当前第i个数的数
从i - 1向前枚举的过程其实和栈从栈顶向栈底弹出元素的过程是一致的,而且在这个过程中,有些数据是不会被使用到的,比如栈内元素aka_kak < ak−1a_{k-1}ak−1 那么ak−1a_{k-1}ak−1在这个栈中就不会被作为答案
因此整个过程就是维护这个栈的单调性



import java.util.*;
class Main{
static final int N = 100010;
static int[] arr = new int[N];
static int[] stack = new int[N];
static int top = -1;
public static void main(String[] agrs) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
for(int i = 0; i < n; i++) {
arr[i] = scanner.nextInt();
}
for(int i = 0; i < n; i ++) {
//将栈中所有比当前数大的弹出
while(top != -1 && stack[top] >= arr[i]) {
top--;
}
if(top == -1) {
System.out.print("-1 ");
} else {
System.out.print(stack[top] + " ");
}
//将当前数入栈
stack[++top] = arr[i];
}
}
}
7799

被折叠的 条评论
为什么被折叠?



