import java.util.*; /** * NC115 栈和排序 * @author d3y1 */ public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * 栈排序 * @param a int整型一维数组 描述入栈顺序 * @return int整型一维数组 */ public int[] solve (int[] a) { // return solution1(a); // return solution2(a); return solution3(a); } /** * 模拟法: Stack+TreeSet * @param a * @return */ private int[] solution1(int[] a){ int n = a.length; TreeSet<Integer> treeSet = new TreeSet<>((o1, o2) -> (o2-o1)); for(int i=n-1; i>=0; i--){ treeSet.add(a[i]); if(a[i] == n){ break; } } int max = treeSet.pollFirst(); int[] result = new int[n]; Stack<Integer> stack = new Stack<>(); int i = 0; for(int num: a){ stack.push(num); treeSet.remove(num); if(stack.peek() == max){ result[i++] = stack.pop(); while(!stack.isEmpty() && !treeSet.isEmpty() && stack.peek()>treeSet.first()){ result[i++] = stack.pop(); } if(!treeSet.isEmpty()){ max = treeSet.pollFirst(); } } } while(!stack.isEmpty()){ result[i++] = stack.pop(); } return result; } /** * 模拟法: Stack(简化) * @param a * @return */ private int[] solution2(int[] a){ int n = a.length; // rMax[i]: i右侧最大值(不包括自身) int[] rMax = new int[n]; int max = a[n-1]; for(int i=n-2; i>=0; i--){ max = Math.max(max, a[i+1]); rMax[i] = max; } int[] result = new int[n]; Stack<Integer> stack = new Stack<>(); for(int i=0,j=0; i<n; i++){ stack.push(a[i]); if(stack.peek() == max){ result[j++] = stack.pop(); // rMax[n-1]=0 全部弹出 while(!stack.isEmpty() && stack.peek()>rMax[i]){ result[j++] = stack.pop(); } max = rMax[i]; } } return result; } /** * 模拟法: Stack(再简化) * @param a * @return */ private int[] solution3(int[] a){ int n = a.length; // rMax[i]: i右侧最大值(包括自身) int[] rMax = new int[n]; rMax[n-1] = a[n-1]; for(int i=n-2; i>=0; i--){ rMax[i] = Math.max(rMax[i+1], a[i]); } int[] result = new int[n]; Stack<Integer> stack = new Stack<>(); int j = 0; for(int i=0; i<n; i++){ while(!stack.isEmpty() && stack.peek()>rMax[i]){ result[j++] = stack.pop(); } stack.push(a[i]); } while(!stack.isEmpty()){ result[j++] = stack.pop(); } return result; } }