友情支持

如果您觉得这个笔记对您有所帮助,看在D瓜哥码这么多字的辛苦上,请友情支持一下,D瓜哥感激不尽,😜

支付宝

微信

有些打赏的朋友希望可以加个好友,欢迎关注D 瓜哥的微信公众号,这样就可以通过公众号的回复直接给我发信息。

wx jikerizhi

公众号的微信号是: jikerizhi因为众所周知的原因,有时图片加载不出来。 如果图片加载不出来可以直接通过搜索微信号来查找我的公众号。

786. 第 K 个最小的质数分数

给你一个按递增顺序排序的数组 arr 和一个整数 k。数组 arr1 和若干 质数 组成,且其中所有整数互不相同。

对于每对满足 0 <= i < j < arr.lengthij,可以得到分数 arr[i] / arr[j]

那么第 k 个最小的分数是多少呢? 以长度为 2 的整数数组返回你的答案, 这里 answer[0] == arr[i]answer[1] == arr[j]

示例 1:

输入:arr = [1,2,3,5], k = 3
输出:[2,5]
解释:已构造好的分数,排序后如下所示:
1/5, 1/3, 2/5, 1/2, 3/5, 2/3
很明显第三个最小的分数是 2/5

示例 2:

输入:arr = [1,7], k = 1
输出:[1,7]

提示:

  • 2 <= arr.length <= 1000

  • 1 <= arr[i] <= 3 * 104

  • arr[0] == 1

  • arr[i] 是一个 质数i > 0

  • arr 中的所有数字 互不相同,且按 严格递增 排序

  • 1 <= k <= arr.length * (arr.length - 1) / 2

进阶:你可以设计并实现时间复杂度小于 O(n2) 的算法解决此问题吗?

思路分析

无需将所有分数的分母都乘到相同的数字,使用如下不等式即可完成大小判定:

\$\frac{a}{b} < \frac{c}{d} \Leftrightarrow a\cdot d < b \cdot c\$
无需保存所有的分数,只需要保存最小 K 个分数即可,多余的分时,直接舍弃。另外,可以直接将分数计算成浮点数就可以直接比较大小了。
  • 一刷

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
/**
 * @author D瓜哥 · https://www.diguage.com
 * @since 2026-06-20 21:28:40
 */
public int[] kthSmallestPrimeFraction(int[] arr, int k) {
  PriorityQueue<int[]> queue = new PriorityQueue<>(k + 1,
    (a, b) -> Long.compare((long) a[1] * b[0], (long) a[0] * b[1]));
  for (int i = 0; i < arr.length; i++) {
    for (int j = arr.length - 1; j > i; j--) {
      queue.offer(new int[]{arr[i], arr[j]});
      if (queue.size() > k) {
        queue.poll();
      }
    }
  }
  return queue.poll();
}