package class39; // 来自腾讯 // 给定一个长度为n的数组arr,求有多少个子数组满足 : // 子数组两端的值,是这个子数组的最小值和次小值,最小值和次小值谁在最左和最右无所谓 // n<=100000(10^5) n*logn O(N) public class Code02_ValidSequence { public static int nums(int[] arr) { if (arr == null || arr.length < 2) { return 0; } int n = arr.length; int[] values = new int[n]; int[] times = new int[n]; int size = 0; int ans = 0; for (int i = 0; i < arr.length; i++) { while (size != 0 && values[size - 1] > arr[i]) { size--; ans += times[size] + cn2(times[size]); } if (size != 0 && values[size - 1] == arr[i]) { times[size - 1]++; } else { values[size] = arr[i]; times[size++] = 1; } } while (size != 0) { ans += cn2(times[--size]); } for (int i = arr.length - 1; i >= 0; i--) { while (size != 0 && values[size - 1] > arr[i]) { ans += times[--size]; } if (size != 0 && values[size - 1] == arr[i]) { times[size - 1]++; } else { values[size] = arr[i]; times[size++] = 1; } } return ans; } public static int cn2(int n) { return (n * (n - 1)) >> 1; } // 为了测试 // 暴力方法 public static int test(int[] arr) { if (arr == null || arr.length < 2) { return 0; } int ans = 0; for (int s = 0; s < arr.length; s++) { for (int e = s + 1; e < arr.length; e++) { int max = Math.max(arr[s], arr[e]); boolean valid = true; for (int i = s + 1; i < e; i++) { if (arr[i] < max) { valid = false; break; } } ans += valid ? 1 : 0; } } return ans; } // 为了测试 public static int[] randomArray(int n, int v) { int[] arr = new int[n]; for (int i = 0; i < n; i++) { arr[i] = (int) (Math.random() * v); } return arr; } // 为了测试 public static void printArray(int[] arr) { for (int num : arr) { System.out.print(num + " "); } System.out.println(); } // 为了测试 public static void main(String[] args) { int n = 30; int v = 30; int testTime = 100000; System.out.println("测试开始"); for (int i = 0; i < testTime; i++) { int m = (int) (Math.random() * n); int[] arr = randomArray(m, v); int ans1 = nums(arr); int ans2 = test(arr); if (ans1 != ans2) { System.out.println("出错了!"); printArray(arr); System.out.println(ans1); System.out.println(ans2); } } System.out.println("测试结束"); } }