package 第02期.mca_02; import java.util.PriorityQueue; // 每周有营养的大厂算法面试题 // 课时101~课时103 // 来自谷歌 // 给定一个数组arr,长度为n // 表示n个服务员,每个人服务一个人的时间 // 给定一个正数m,表示有m个人等位 // 如果你是刚来的人,请问你需要等多久? // 假设:m远远大于n,比如n<=1000, m <= 10的9次方,该怎么做? public class Code02_MinWaitingTime { // arr中,>= num 的最左位置,返回位置!下标! // arr中,没有 >= num的数字,返回-1,表示不存在 public static int find(int[] arr, int num) { int l = 0; int r = arr.length - 1; int m = 0; int ans = -1; while (l <= r) { m = (l + r) / 2; if (arr[m] >= num) { ans = m; r = m - 1; } else { l = m + 1; } } return ans; } public static int minWaitingTime1(int[] arr, int m) { if (arr == null || arr.length == 0) { return -1; } PriorityQueue heap = new PriorityQueue<>((a, b) -> (a[0] - b[0])); int n = arr.length; for (int i = 0; i < n; i++) { heap.add(new int[] { 0, arr[i] }); } for (int i = 0; i < m; i++) { int[] cur = heap.poll(); cur[0] += cur[1]; heap.add(cur); } return heap.peek()[0]; } public static int minWaitingTime2(int[] arr, int m) { if (arr == null || arr.length == 0) { return -1; } int best = Integer.MAX_VALUE; for (int num : arr) { best = Math.min(best, num); } int left = 0; int right = best * m; int mid = 0; int near = 0; while (left <= right) { mid = (left + right) / 2; int cover = 0; for (int num : arr) { cover += (mid / num) + 1; } if (cover >= m + 1) { near = mid; right = mid - 1; } else { left = mid + 1; } } return near; } // 为了测试 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) + 1; } return arr; } // 为了测试 public static void main(String[] args) { int len = 50; int value = 30; int mMax = 3000; int testTime = 20000; System.out.println("测试开始"); for (int i = 0; i < testTime; i++) { int n = (int) (Math.random() * len) + 1; int[] arr = randomArray(n, value); int m = (int) (Math.random() * mMax); int ans1 = minWaitingTime1(arr, m); int ans2 = minWaitingTime2(arr, m); if (ans1 != ans2) { System.out.println("出错了!"); for (int num : arr) { System.out.print(num + " "); } System.out.println(); System.out.println("m : " + m); System.out.println(ans1); System.out.println(ans2); break; } } System.out.println("测试结束"); } }