当我脑子里出现这个轨迹时,单调栈的原理全想明白了
5 3 4 2 1
import java.util.*; import java.io.*; public class Main{ public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(br.readLine()); String[] stringsNums = br.readLine().split(" "); int[] arr = new int[n]; for(int i=0;i<n;i++){ arr[i]=Integer.parseInt(stringsNums[i]); } int[][] res = getResult(arr,n); StringBuilder builder = new StringBuilder(); for (int i = 0; i < n; ++i) { builder.append(res[i][0]).append(' ').append(res[i][1]).append('\n'); } System.out.println(builder.toString()); } //单调栈思想 //第一个元素下标入栈,下一个如果大于栈顶元素则直接入栈, //下一个如果小于栈顶元素,这时可以得到当前栈顶元素的 左右位置结果信息, //栈顶元素出栈,继续对比,如果待入栈元素仍然小于栈顶,则得到了当前栈顶的左右位置结果 //栈顶元素继续出栈,直到栈顶元素大于待入栈的元素 //arr入栈完毕后,如果栈中还有元素,则右位置结果一定为-1 //不停出栈,可得到左位置结果信息, //如此反复,直到出栈完毕,最后一个元素的左位置信息一定为-1 public static int[][] getResult(int[] arr,int size){ // if(size==1) return new int[][]{{-1,-1}}; int[][] result = new int[size][2]; Stack<Integer> stack = new Stack<>(); for(int i=0;i<size;i++){ if(stack.isEmpty()){ stack.push(i); }else{ while(!stack.isEmpty()){ //大于栈顶元素,直接入栈 if(arr[i]>arr[stack.peek()]){ stack.push(i); break; }else{ //得到了栈顶元素的结果信息 int curIndex = stack.pop(); result[curIndex][1]=i ;//右位置 if(stack.isEmpty()){ result[curIndex][0]=-1;//左位置 //栈空了,没必要继续循环了,入栈,退出while stack.push(i); break; }else{ result[curIndex][0]=stack.peek();//左位置 } } } } } //处理特殊情况 //1、size=1的情况 //2、最后一个元素小于栈中所有元素 //3、最后一个元素大于栈顶元素 //4、最后一个元素不完全大于栈中所有元素 while(!stack.isEmpty()){ //得到了栈顶元素的结果信息 int curIndex = stack.pop(); result[curIndex][1]=-1 ;//右位置 if(stack.isEmpty()){ result[curIndex][0]=-1;//左位置 }else{ result[curIndex][0]=stack.peek();//左位置 } } return result; } }