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] = pand 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.

这道题给了我们一个有序数组,里面是1和一些质数,说是对于任意两个数,都可以组成一个 [0, 1] 之间分数,让求第K小的分数是什么,题目中给的例子也很好的说明了题意。那么最直接暴力的解法就是遍历出所有的分数,然后再进行排序,返回第K小的即可。但是这种无脑暴力搜索的方法 OJ 是不答应的,无奈,只能想其他的解法。由于数组是有序的,所以最小的分数肯定是由第一个数字和最后一个数字组成的,而接下来第二小的分数就不确定是由第二个数字和最后一个数字组成的,还是由第一个数字跟倒数第二个数字组成的。这里用一个最小堆来存分数,那么每次取的时候就可以将最小的分数取出来,由于前面说了,不能遍历所有的分数都存入最小堆,那么该怎么办呢,可以先存n个,哪n个呢?其实就是数组中的每个数字都和最后一个数字组成的分数。由于需要取出第K小的分数,那么在最小堆中取K个分数就可以了,第一个取出的分数就是那个由第一个数字和最后一个数字组成的最小的分数,然后就是精髓所在了,此时将分母所在的位置前移一位,还是和当前的分子组成新的分数,这里即为第一个数字和倒数第二个数字组成的分数,存入最小堆中,那么由于之前已经将第二个数字和倒数第一个数字组成的分数存入了最小堆,所以不用担心第二小的分数不在堆中,这样每取出一个分数,都新加一个稍稍比取出的大一点的分数,这样取出了第K个分数即为所求,参见代码如下:

解法一:

class Solution {
public:
vector<int> kthSmallestPrimeFraction(vector<int>& A, int K) {
priority_queue<pair<double, pair<int, int>>> q;
for (int i = ; i < A.size(); ++i) {
q.push({-1.0 * A[i] / A.back(), {i, A.size() - }});
}
while (--K) {
auto t = q.top().second; q.pop();
--t.second;
q.push({-1.0 * A[t.first] / A[t.second], {t.first, t.second}});
}
return {A[q.top().second.first], A[q.top().second.second]};
}
};

其实这道题比较经典的解法是用二分搜索法 Binary Search,使用的二分搜索法是博主归纳总结帖 LeetCode Binary Search Summary 二分搜索法小结 中的第四种,即二分法的判定条件不是简单的大小关系,而是可以抽离出子函数的情况,下面来看具体怎么弄。这种高级的二分搜索法在求第K小的数的时候经常使用,比如 Kth Smallest Element in a Sorted MatrixKth Smallest Number in Multiplication Table,和 Find K-th Smallest Pair Distance 等。思路都是用 mid 当作 candidate,然后统计小于 mid 的个数 cnt,和K进行比较,从而确定折半的方向。这道题也是如此,mid 为候选的分数值,刚开始时是 0.5,然后需要统计出不大于 mid 的分数都个数 cnt,同时也需要找出最接近 mid 的分数,当作返回的候选值,因为一旦 cnt 等于K了,直接将这个候选值返回即可,这个候选值分数是由p和q来表示的,其中p表示分子,初始化为0,q表示分母,初始化为1(因为除数不能为0),在内部的 while 循环退出时,分数 A[i]/A[j] 就是最接近 mid 的候选者,此时假如 p/q 要小于 A[i]/A[j],就要分别更新p和q。否则如果 cnt 小于K,说明应该增大一些 mid,将 left 赋值为 mid,反之如果 cnt 大于K,需要减小 mid,将 right 赋值为 mid,参见代码如下:

解法二:

class Solution {
public:
vector<int> kthSmallestPrimeFraction(vector<int>& A, int K) {
double left = , right = ;
int p = , q = , cnt = , n = A.size();
while (true) {
double mid = left + (right - left) / 2.0;
cnt = ; p = ;
for (int i = , j = ; i < n; ++i) {
while (j < n && A[i] > mid * A[j]) ++j;
cnt += n - j;
if (j < n && p * A[j] < q * A[i]) {
p = A[i];
q = A[j];
}
}
if (cnt == K) return {p, q};
if (cnt < K) left = mid;
else right = mid;
}
}
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/786

类似题目:

Find K Pairs with Smallest Sums

Kth Smallest Element in a Sorted Matrix

Kth Smallest Number in Multiplication Table

Find K-th Smallest Pair Distance

参考资料:

https://leetcode.com/problems/k-th-smallest-prime-fraction/

https://leetcode.com/problems/k-th-smallest-prime-fraction/discuss/115531/C++-9lines-priority-queue

https://leetcode.com/problems/k-th-smallest-prime-fraction/discuss/115819/Summary-of-solutions-for-problems-%22reducible%22-to-LeetCode-378

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] K-th Smallest Prime Fraction 第K小的质分数的更多相关文章

  1. [LeetCode] 786. K-th Smallest Prime Fraction 第K小的质分数

    A sorted list A contains 1, plus some number of primes.  Then, for every p < q in the list, we co ...

  2. 786. K-th Smallest Prime Fraction

    A sorted list A contains 1, plus some number of primes.  Then, for every p < q in the list, we co ...

  3. [Swift]LeetCode786. 第 K 个最小的素数分数 | K-th Smallest Prime Fraction

    A sorted list A contains 1, plus some number of primes.  Then, for every p < q in the list, we co ...

  4. 【LeetCode】1022. Smallest Integer Divisible by K 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...

  5. 【leetcode】1022. Smallest Integer Divisible by K

    题目如下: Given a positive integer K, you need find the smallest positive integer N such that N is divis ...

  6. [LeetCode] Find K-th Smallest Pair Distance 找第K小的数对儿距离

    Given an integer array, return the k-th smallest distance among all the pairs. The distance of a pai ...

  7. [LeetCode] 378. Kth Smallest Element in a Sorted Matrix 有序矩阵中第K小的元素

    Given a n x n matrix where each of the rows and columns are sorted in ascending order, find the kth ...

  8. [leetcode] 230. Kth Smallest Element in a BST 找出二叉搜索树中的第k小的元素

    题目大意 https://leetcode.com/problems/kth-smallest-element-in-a-bst/description/ 230. Kth Smallest Elem ...

  9. [LeetCode] 230. Kth Smallest Element in a BST 二叉搜索树中的第K小的元素

    Given a binary search tree, write a function kthSmallest to find the kth smallest element in it. Not ...

随机推荐

  1. HDU 5968(异或计算 暴力)

    题意是在一个数列中找到一段连续的子串使其异或值与所给值最接近,求出子串长度,若有多组结果,输出最大长度. 做题之前一定多注意数据范围,这道题就可以直接暴力,用数组 p[ i ][ j ] 表示长度为 ...

  2. javaScript事件机制深入学习(事件冒泡,事件捕获,事件绑定方式,移除事件方式,阻止浏览器默认行为,事件委托,模拟浏览器事件,自定义事件)

    前言 JavaScript与HTML之间的交互是通过事件实现的.事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间.可以使用侦听器(或处理程序)来预订事件,以便事件发生时执行相应的代码.这种在传统软 ...

  3. JGUI源码:解决手机端点击出现半透明阴影(4)

    下面开始进入正题,问题发现与解决 1.According解决手机浏览器点击出现半透明阴影 手机下点击有白色蒙版,原始效果如下,看起来很不协调 2.解决办法:增加 -webkit-tap-highlig ...

  4. [物理学与PDEs]第1章第3节 真空中的 Maxwell 方程组, Lorentz 力 3.2 Lorentz 力

    1. Lorentz 假定, 不论带电体的运动状态如何, 其所受的力密度 (单位体积所受的力) 为 $$\bex {\bf F}=\rho {\bf E}+{\bf j}\times{\bf B} = ...

  5. Codeforces Round #527 (Div. 3) . F Tree with Maximum Cost

    题目链接 题意:给你一棵树,让你找一个顶点iii,使得这个点的∑dis(i,j)∗a[j]\sum dis(i,j)*a[j]∑dis(i,j)∗a[j]最大.dis(i,j)dis(i,j)dis( ...

  6. JSON 之 SuperObject(11): TSuperTableString、TSuperAvlEntry

    JSON 之 SuperObject(11): TSuperTableString.TSuperAvlEntry - 万一 - 博客园http://www.cnblogs.com/del/archiv ...

  7. 肺结节CT影像特征提取(二)——肺结节CT图像特征提取算法描述

    摘自本人毕业论文<肺结节CT影像特征提取算法研究> 医学图像特征提取可以认为是基于图像内容提取必要特征,医学图像中需要什么特征基于研究需要,提取合适的特征.相对来说,医学图像特征提取要求更 ...

  8. PostgreSQL快速入门

    一.PostgreSQL是什么? PostgreSQL是一个功能强大的开源对象关系数据库管理系统(ORDBMS). 用于安全地存储数据; 支持最佳做法,并允许在处理请求时检索它们. PostgreSQ ...

  9. ApowerMirror投屏(手机投屏电脑、电脑投屏到手机)

    使用步骤    1. 亲测 使用Apowersoft ApowerMirror v1.4.2.zip版本      2.Apowersoft ApowerMirror v1.4.2.zip 解压安装 ...

  10. 初学python之路-day01

    第一天学习python,先了解到了进制之间的转换关系. 如二进制与十进制的转换,如1111转成十进制为15,1111从左向右可看出2^3+2^2+2^1+2^0为8+4+2+1=15.记住前8位1的二 ...