JAVA程序设计:第 K 个最小的素数分数(LeetCode:786)

一个已排序好的表 A,其包含 1 和其他一些素数.  当列表中的每一个 p

那么第 k 个最小的分数是多少呢?  以整数数组的形式返回你的答案, 这里 answer[0] = p 且 answer[1] = q.

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

输入: A = [1, 7], K = 1
输出: [1, 7]
注意:

A 的取值范围在 2 — 2000.
每个 A[i] 的值在 1 —30000.
K 取值范围为 1 —A.length * (A.length - 1) / 2

方法一:二分答案,我们通过枚举第k个分母应该是多少进行二分,知道找到该答案。

class Solution {
    public int[] kthSmallestPrimeFraction(int[] A, int K) {
    	
    	double l=0,r=1;
    	int[] ans= new int[]{0,1};
    	
    	while(r-l>1e-9) {
    		double mid=l+(r-l)/2.0;
    		int[] res=work(mid,A);
    		if(res[0]=0 && numer*A[j]

方法二:堆,使用一个堆记录所有以 A[j] 为分母且未被弹出的最小分数。依次从堆中弹出 K-1 个元素,此时堆顶的分数就是结果。由于K有n*(n-1)/2这么大,因此方法二的复杂度相对于方法一要高很多。

class Solution {
    public int[] kthSmallestPrimeFraction(int[] A, int K) {
    	
    	PriorityQueue q=new PriorityQueue((a,b)->A[a[0]]*A[b[1]]-A[a[1]]*A[b[0]]);
    	
    	for(int i=1;i0) {
    		int[] res=q.poll();
    		if(res[0]++

 

你可能感兴趣的:(JAVA程序设计:第 K 个最小的素数分数(LeetCode:786))