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

314 阅读1分钟

这是我参与11月更文挑战的第27天,活动详情查看:2021最后一次更文挑战

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

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

对于每对满足 0 < i < j < arr.length 的 i 和 j ,可以得到分数 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 * 10410^4
  • arr[0] == 1
  • arr[i] 是一个 素数 ,i > 0
  • arr 中的所有数字 互不相同 ,且按 严格递增 排序
  • 1 <= k <= arr.length * (arr.length - 1) / 2

解题思路

题目需要求得第 k 个最小的分数,而分数定义为每对满足 0 < i < j < arr.length 的 i 和 j ,得到的arr[i] / arr[j] ,因为数组arr是按递增顺序排序的,因此分数都是小于0的数字。为了避免浮点数的精度丢失,当我们比较当我们比较两个分数 ab\dfrac{a}{b}和 cd\dfrac{c}{d}时,我们可以使用:a×d<b×ca \times d < b \times c来替代 ab<cd\dfrac{a}{b} < \dfrac{c}{d} 的判断,二者是等价的,这样就可以避免计算机浮点数丢失造成的问题。因此我们在排序中需要根据上述规则进行自定义的排序,然后选出第k个最小的分数。

代码

class Solution {
public:
    vector<int> kthSmallestPrimeFraction(vector<int> &arr, int k) {

        vector<pair<int, int>> cnt;
        for (int i = 0; i < arr.size(); ++i) {

            for (int j = i - 1; j >= 0; --j) {
                cnt.emplace_back(arr[j], arr[i]);
            }
        }
        sort(cnt.begin(), cnt.end(), [&](const auto &x, const auto &y) {
            return x.first * y.second < x.second * y.first;
        });
        return {cnt[k-1].first,cnt[k-1].second};
    }
};