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.

116 lines
2.7 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 class04;
import java.util.ArrayList;
import java.util.HashMap;
public class Code01_QueryHobby {
/*
* 今日头条原题
*
* 数组为{3, 2, 2, 3, 1},查询为(0, 3, 2)。意思是在数组里下标0~3这个范围上有几个2返回2。
* 假设给你一个数组arr对这个数组的查询非常频繁请返回所有查询的结果
*
*/
public static class QueryBox1 {
private int[] arr;
public QueryBox1(int[] array) {
arr = new int[array.length];
for (int i = 0; i < arr.length; i++) {
arr[i] = array[i];
}
}
public int query(int L, int R, int v) {
int ans = 0;
for (; L <= R; L++) {
if (arr[L] == v) {
ans++;
}
}
return ans;
}
}
public static class QueryBox2 {
private HashMap<Integer, ArrayList<Integer>> map;
public QueryBox2(int[] arr) {
map = new HashMap<>();
for (int i = 0; i < arr.length; i++) {
if (!map.containsKey(arr[i])) {
map.put(arr[i], new ArrayList<>());
}
map.get(arr[i]).add(i);
}
}
public int query(int L, int R, int value) {
if (!map.containsKey(value)) {
return 0;
}
ArrayList<Integer> indexArr = map.get(value);
// 查询 < L 的下标有几个
int a = countLess(indexArr, L);
// 查询 < R+1 的下标有几个
int b = countLess(indexArr, R + 1);
return b - a;
}
// 在有序数组arr中用二分的方法数出<limit的数有几个
// 也就是用二分法,找到<limit的数中最右的位置
private int countLess(ArrayList<Integer> arr, int limit) {
int L = 0;
int R = arr.size() - 1;
int mostRight = -1;
while (L <= R) {
int mid = L + ((R - L) >> 1);
if (arr.get(mid) < limit) {
mostRight = mid;
L = mid + 1;
} else {
R = mid - 1;
}
}
return mostRight + 1;
}
}
public static int[] generateRandomArray(int len, int value) {
int[] ans = new int[(int) (Math.random() * len) + 1];
for (int i = 0; i < ans.length; i++) {
ans[i] = (int) (Math.random() * value) + 1;
}
return ans;
}
public static void main(String[] args) {
int len = 300;
int value = 20;
int testTimes = 1000;
int queryTimes = 1000;
System.out.println("test begin");
for (int i = 0; i < testTimes; i++) {
int[] arr = generateRandomArray(len, value);
int N = arr.length;
QueryBox1 box1 = new QueryBox1(arr);
QueryBox2 box2 = new QueryBox2(arr);
for (int j = 0; j < queryTimes; j++) {
int a = (int) (Math.random() * N);
int b = (int) (Math.random() * N);
int L = Math.min(a, b);
int R = Math.max(a, b);
int v = (int) (Math.random() * value) + 1;
if (box1.query(L, R, v) != box2.query(L, R, v)) {
System.out.println("Oops!");
}
}
}
System.out.println("test end");
}
}