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.

108 lines
2.5 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package class_2022_10_2_week;
import java.util.HashMap;
// 来自小红书
// 小A认为如果在数组中有一个数出现了至少k次
// 且这个数是该数组的众数,即出现次数最多的数之一
// 那么这个数组被该数所支配
// 显然当k比较大的时候有些数组不被任何数所支配
// 现在小A拥有一个长度为n的数组她想知道内部有多少个区间是被某个数支配的
// 2 <= k <= n <= 100000
// 1 <= 数组的值 <= n
public class Code01_RangesHasDominateNumber {
// 暴力方法
// 为了验证
// 时间复杂度O(N^3)
public static int dominates1(int[] arr, int k) {
int n = arr.length;
int ans = 0;
for (int l = 0; l < n; l++) {
for (int r = l; r < n; r++) {
if (ok(arr, l, r, k)) {
ans++;
}
}
}
return ans;
}
public static boolean ok(int[] arr, int l, int r, int k) {
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int i = l; i <= r; i++) {
map.put(arr[i], map.getOrDefault(arr[i], 0) + 1);
}
for (int times : map.values()) {
if (times >= k) {
return true;
}
}
return false;
}
// 正式方法
// 时间复杂度O(N)
public static int dominates2(int[] arr, int k) {
int n = arr.length;
// 总数量
int all = n * (n + 1) / 2;
// 不被支配的区间数量
int except = 0;
// 次数表
// 0 : 0
// 1 : 0
// 2 : 0
int[] cnt = new int[n + 1];
// l ... r
// 窗口用这个形式[l,r)
// l...r-1 r(x)
// l == 0 r == 0 [l,r) 一个数也没有
// l == 0 r == 1 [0..0]
for (int l = 0, r = 0; l < n; l++) {
// [r] 即将要进来的
// cnt[arr[r]] + 1 < k
while (r < n && cnt[arr[r]] + 1 < k) {
// cnt[arr[r]]++;
// r++
cnt[arr[r++]]++;
}
// l..l
// l..l+1
// l..l+2
// l..r-1
except += r - l;
cnt[arr[l]]--;
}
return all - except;
}
// 为了测试
public static int[] randomArray(int n) {
int[] ans = new int[n];
for (int i = 0; i < n; i++) {
ans[i] = (int) (Math.random() * n) + 1;
}
return ans;
}
// 为了测试
public static void main(String[] args) {
int N = 100;
int testTimes = 5000;
System.out.println("测试开始");
for (int i = 0; i < testTimes; i++) {
int n = (int) (Math.random() * N) + 1;
int[] arr = randomArray(n);
int k = (int) (Math.random() * n) + 1;
int ans1 = dominates1(arr, k);
int ans2 = dominates2(arr, k);
if (ans1 != ans2) {
System.out.println("出错了!");
}
}
System.out.println("测试结束");
}
}