第 K 个最小的质数分数
难度:
标签:
题目描述
代码结果
运行时间: 51 ms, 内存: 16.1 MB
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
/**
* 思路:
* 使用 Java Stream API 创建所有可能的分数对。
* 将分数对根据分数排序,并获取第 k 小的分数对。
*/
public class Solution {
public int[] kthSmallestPrimeFraction(int[] arr, int k) {
List<int[]> fractions = IntStream.range(0, arr.length)
.boxed()
.flatMap(i -> IntStream.range(i + 1, arr.length)
.mapToObj(j -> new int[]{i, j}))
.sorted((a, b) -> Double.compare((double) arr[a[0]] / arr[a[1]], (double) arr[b[0]] / arr[b[1]]))
.collect(Collectors.toList());
return new int[]{arr[fractions.get(k - 1)[0]], arr[fractions.get(k - 1)[1]]};
}
}
解释
方法:
该题解使用二分查找的思路。首先将查找范围设为 [0, 1],因为分数的取值范围在 0 到 1 之间。然后在每次二分查找时,统计小于等于 mid 的分数个数 count。如果 count 等于 k,说明找到了第 k 小的分数;如果 count 小于 k,说明第 k 小的分数在 (mid, right] 范围内,缩小查找范围为 [mid, right];如果 count 大于 k,说明第 k 小的分数在 [left, mid) 范围内,缩小查找范围为 [left, mid]。在统计 count 的过程中,使用双指针分别指向分子和分母,并记录最大的分数。
时间复杂度:
O(nlog(1/eps))
空间复杂度:
O(1)
代码细节讲解
🦆
在二分查找中,为什么选择将查找范围初始化为[0, 1],而不是基于数组`arr`的具体数值来定义范围?
▷🦆
如何确保在while循环中的二分查找过程最终能够停止?即,什么条件下会退出循环?
▷🦆
在统计小于等于`mid`的分数个数时,为什么使用双指针方法有效?这种方法有哪些潜在的限制或假设?
▷🦆
题解中提到记录最大的分数,这是否与寻找第k小的分数矛盾?是否应该记录最小的分数而不是最大的分数?
▷相关问题
有序矩阵中第 K 小的元素
给你一个 n x n
矩阵 matrix
,其中每行和每列元素均按升序排序,找到矩阵中第 k
小的元素。
请注意,它是 排序后 的第 k
小元素,而不是第 k
个 不同 的元素。
你必须找到一个内存复杂度优于 O(n2)
的解决方案。
示例 1:
输入:matrix = [[1,5,9],[10,11,13],[12,13,15]], k = 8 输出:13 解释:矩阵中的元素为 [1,5,9,10,11,12,13,13,15],第 8 小元素是 13
示例 2:
输入:matrix = [[-5]], k = 1 输出:-5
提示:
n == matrix.length
n == matrix[i].length
1 <= n <= 300
-109 <= matrix[i][j] <= 109
- 题目数据 保证
matrix
中的所有行和列都按 非递减顺序 排列 1 <= k <= n2
进阶:
- 你能否用一个恒定的内存(即
O(1)
内存复杂度)来解决这个问题? - 你能在
O(n)
的时间复杂度下解决这个问题吗?这个方法对于面试来说可能太超前了,但是你会发现阅读这篇文章( this paper )很有趣。
乘法表中第k小的数
几乎每一个人都用 乘法表。但是你能在乘法表中快速找到第 k
小的数字吗?
乘法表是大小为 m x n
的一个整数矩阵,其中 mat[i][j] == i * j
(下标从 1 开始)。
给你三个整数 m
、n
和 k
,请你在大小为 m x n
的乘法表中,找出并返回第 k
小的数字。
示例 1:

输入:m = 3, n = 3, k = 5 输出:3 解释:第 5 小的数字是 3 。
示例 2:

输入:m = 2, n = 3, k = 6 输出:6 解释:第 6 小的数字是 6 。
提示:
1 <= m, n <= 3 * 104
1 <= k <= m * n
找出第 K 小的数对距离
数对 (a,b)
由整数 a
和 b
组成,其数对距离定义为 a
和 b
的绝对差值。
给你一个整数数组 nums
和一个整数 k
,数对由 nums[i]
和 nums[j]
组成且满足 0 <= i < j < nums.length
。返回 所有数对距离中 第 k
小的数对距离。
示例 1:
输入:nums = [1,3,1], k = 1 输出:0 解释:数对和对应的距离如下: (1,3) -> 2 (1,1) -> 0 (3,1) -> 2 距离第 1 小的数对是 (1,1) ,距离为 0 。
示例 2:
输入:nums = [1,1,1], k = 2 输出:0
示例 3:
输入:nums = [1,6,1], k = 3 输出:5
提示:
n == nums.length
2 <= n <= 104
0 <= nums[i] <= 106
1 <= k <= n * (n - 1) / 2