当我脑子里出现这个轨迹时,单调栈的原理全想明白了

         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;
    }
}