786. 第 K 个最小的素数分数
题目:
思路:
【1】将全部数据弄好然后排序取出结果
【2】利用优先队列实现堆的思想
【3】利用二分的方式进行优化
代码展示:
【1】将全部数据弄好然后排序取出结果
//时间419 ms 击败 18.67% //内存70.1 MB 击败 12.1% //把所有的数据都填进集合里面然后对集合进行排序, //然后通过下标拿出来 class Solution { public int[] kthSmallestPrimeFraction(int[] arr, int k) { int n = arr.length; List<int[]> frac = new ArrayList<int[]>(); for (int i = 0; i < n; ++i) { for (int j = i + 1; j < n; ++j) { frac.add(new int[]{arr[i], arr[j]}); } } Collections.sort(frac, (x, y) -> x[0] * y[1] - y[0] * x[1]); return frac.get(k - 1); } }
【2】利用优先队列实现堆的思想
//时间264 ms 击败 48.67% //内存43.3 MB 击败 48.67% class Solution { public int[] kthSmallestPrimeFraction(int[] arr, int k) { int n = arr.length; PriorityQueue<int[]> pq = new PriorityQueue<int[]>((x, y) -> arr[x[0]] * arr[y[1]] - arr[y[0]] * arr[x[1]]); for (int j = 1; j < n; ++j) { pq.offer(new int[]{0, j}); } for (int i = 1; i < k; ++i) { int[] frac = pq.poll(); int x = frac[0], y = frac[1]; if (x + 1 < y) { pq.offer(new int[]{x + 1, y}); } } return new int[]{arr[pq.peek()[0]], arr[pq.peek()[1]]}; } }
【3】利用二分的方式进行优化
//时间3 ms 击败 97.67% //内存40.3 MB 击败 99.33% class Solution { public int[] kthSmallestPrimeFraction(int[] arr, int k) { int n = arr.length; double left = 0.0, right = 1.0; while (true) { double mid = (left + right) / 2; int i = -1, count = 0; // 记录最大的分数 int x = 0, y = 1; for (int j = 1; j < n; ++j) { while ((double) arr[i + 1] / arr[j] < mid) { ++i; if (arr[i] * y > arr[j] * x) { x = arr[i]; y = arr[j]; } } count += i + 1; } if (count == k) { return new int[]{x, y}; } if (count < k) { left = mid; } else { right = mid; } } } }