package class25; import java.util.List; import java.util.ArrayList; import java.util.Stack; public class Code01_MonotonousStack { // arr = [ 3, 1, 2, 3] // 0 1 2 3 // [ // 0 : [-1, 1] // 1 : [-1, -1] // 2 : [ 1, -1] // 3 : [ 2, -1] // ] public static int[][] getNearLessNoRepeat(int[] arr) { int[][] res = new int[arr.length][2]; // 只存位置! Stack stack = new Stack<>(); for (int i = 0; i < arr.length; i++) { // 当遍历到i位置的数,arr[i] while (!stack.isEmpty() && arr[stack.peek()] > arr[i]) { int j = stack.pop(); int leftLessIndex = stack.isEmpty() ? -1 : stack.peek(); res[j][0] = leftLessIndex; res[j][1] = i; } stack.push(i); } while (!stack.isEmpty()) { int j = stack.pop(); int leftLessIndex = stack.isEmpty() ? -1 : stack.peek(); res[j][0] = leftLessIndex; res[j][1] = -1; } return res; } public static int[][] getNearLess(int[] arr) { int[][] res = new int[arr.length][2]; Stack> stack = new Stack<>(); for (int i = 0; i < arr.length; i++) { // i -> arr[i] 进栈 while (!stack.isEmpty() && arr[stack.peek().get(0)] > arr[i]) { List popIs = stack.pop(); int leftLessIndex = stack.isEmpty() ? -1 : stack.peek().get(stack.peek().size() - 1); for (Integer popi : popIs) { res[popi][0] = leftLessIndex; res[popi][1] = i; } } if (!stack.isEmpty() && arr[stack.peek().get(0)] == arr[i]) { stack.peek().add(Integer.valueOf(i)); } else { ArrayList list = new ArrayList<>(); list.add(i); stack.push(list); } } while (!stack.isEmpty()) { List popIs = stack.pop(); int leftLessIndex = stack.isEmpty() ? -1 : stack.peek().get(stack.peek().size() - 1); for (Integer popi : popIs) { res[popi][0] = leftLessIndex; res[popi][1] = -1; } } return res; } // for test public static int[] getRandomArrayNoRepeat(int size) { int[] arr = new int[(int) (Math.random() * size) + 1]; for (int i = 0; i < arr.length; i++) { arr[i] = i; } for (int i = 0; i < arr.length; i++) { int swapIndex = (int) (Math.random() * arr.length); int tmp = arr[swapIndex]; arr[swapIndex] = arr[i]; arr[i] = tmp; } return arr; } // for test public static int[] getRandomArray(int size, int max) { int[] arr = new int[(int) (Math.random() * size) + 1]; for (int i = 0; i < arr.length; i++) { arr[i] = (int) (Math.random() * max) - (int) (Math.random() * max); } return arr; } // for test public static int[][] rightWay(int[] arr) { int[][] res = new int[arr.length][2]; for (int i = 0; i < arr.length; i++) { int leftLessIndex = -1; int rightLessIndex = -1; int cur = i - 1; while (cur >= 0) { if (arr[cur] < arr[i]) { leftLessIndex = cur; break; } cur--; } cur = i + 1; while (cur < arr.length) { if (arr[cur] < arr[i]) { rightLessIndex = cur; break; } cur++; } res[i][0] = leftLessIndex; res[i][1] = rightLessIndex; } return res; } // for test public static boolean isEqual(int[][] res1, int[][] res2) { if (res1.length != res2.length) { return false; } for (int i = 0; i < res1.length; i++) { if (res1[i][0] != res2[i][0] || res1[i][1] != res2[i][1]) { return false; } } return true; } // for test public static void printArray(int[] arr) { for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + " "); } System.out.println(); } public static void main(String[] args) { int size = 10; int max = 20; int testTimes = 2000000; System.out.println("测试开始"); for (int i = 0; i < testTimes; i++) { int[] arr1 = getRandomArrayNoRepeat(size); int[] arr2 = getRandomArray(size, max); if (!isEqual(getNearLessNoRepeat(arr1), rightWay(arr1))) { System.out.println("Oops!"); printArray(arr1); break; } if (!isEqual(getNearLess(arr2), rightWay(arr2))) { System.out.println("Oops!"); printArray(arr2); break; } } System.out.println("测试结束"); } }