一:题目描述
1.英文描述:
A sorted list A contains 1, plus some number of primes. Then, for every p < q in the list, we consider the fraction p/q.
What is the K-th smallest fraction considered? Return your answer as an array of ints, where answer[0] = p and answer[1] = q.
Examples:
Input: A = [1, 2, 3, 5], K = 3
Output: [2, 5]
Explanation:
The fractions to be considered in sorted order are:
1/5, 1/3, 2/5, 1/2, 3/5, 2/3.
The third fraction is 2/5.
Input: A = [1, 7], K = 1
Output: [1, 7]
Note:
A will have length between 2 and 2000.
Each A[i] will be between 1 and 30000.
K will be between 1 and A.length * (A.length - 1) / 2.
2.中文描述:
786 第 K 个最小的素数分数
一个已排序好的表 A,其包含 1 和其他一些素数. 当列表中的每一个 p<q 时,我们可以构造一个分数 p/q 。
那么第 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。
二:算法分析
思路:
初始时left = 0,right = 1
,在区间[left,right]
使用二分查找找出一个 mid
,记录小于 mid
的分数 好有 count
个,并且记录在mid左边其中最大的一个分数 p/q
。如果count == K
时就说明此时在mid
之前的数刚好有K
个,此时则返回 [p, q]
。若 count < K
时则缩小区间为[mid,right]
,然后重新定义mid
,然 后在按照上述循环。若count > K
时则缩小区间为[left,mid]
,然后重新定义mid
,然后在按照上述循 环。其主要思想就是要用二分查找的思想,找到一个数使得小于其的数恰好为K
个,然后返回其中 最大的即可。
三:代码
#include<iostream>
#include<vector>
using namespace std;
class Solution{ //二分查找
public:
vector<int> kthSmallestPrimeFraction(vector<int>& A, int K)
{
double left = 0, right = 1.0, mid;
int p = 0;
int q = 1;
int Asize = A.size();
int count;
while (true)
{
double mid = (left + right) / 2.0;
count = 0;
p = 0;
for (int i = 0, j = i+1; i < Asize; ++i)
{
while (j < Asize && mid < (double)A[i]/(double)A[j] )
{
++j;
}
count += Asize - j; //记录在 mid 之前数的个数
if (j < Asize && (double)p/(double)q < (double)A[i]/(double)A[j]) //记录此时在mid之前的最大的 p / q
{
p = A[i];
q = A[j];
}
}
if (count == K) //若相等就返回此时的p q
{
return {p, q};
}
else if (count < K) //若 count < K 就缩小区间为[mid,right]
{
left = mid;
}
else //若 count > K 就缩小区间为[left,mid]
{
right = mid;
}
}
}
};