You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

114 lines
2.5 KiB

2 years ago
package class39;
// 来自腾讯
// 给定一个长度为n的数组arr求有多少个子数组满足 :
// 子数组两端的值,是这个子数组的最小值和次小值,最小值和次小值谁在最左和最右无所谓
// n<=10000010^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("测试结束");
}
}