|
| 1 | +/* |
| 2 | + * @lc app=leetcode.cn id=786 lang=cpp |
| 3 | + * |
| 4 | + * [786] 第 K 个最小的素数分数 |
| 5 | + */ |
| 6 | + |
| 7 | +// @lc code=start |
| 8 | +class Solution { |
| 9 | +public: |
| 10 | + // vector<int> kthSmallestPrimeFraction(vector<int>& arr, int k) { |
| 11 | + // int n = arr.size(); |
| 12 | + // vector<vector<int>> vec; |
| 13 | + // for (int i = 0; i < n; i++) { |
| 14 | + // for (int j = i + 1; j < n; j++) { |
| 15 | + // vec.push_back({ arr[i], arr[j] }); |
| 16 | + // } |
| 17 | + // } |
| 18 | + |
| 19 | + // sort(vec.begin(), vec.end(), [](const vector<int>& a, const vector<int>& b) -> bool { |
| 20 | + // return a[0] * b[1] < b[0] * a[1]; |
| 21 | + // }); |
| 22 | + |
| 23 | + // return vec[k-1]; |
| 24 | + // } |
| 25 | + |
| 26 | + vector<int> kthSmallestPrimeFraction(vector<int>& arr, int k) { |
| 27 | + int n = arr.size(); |
| 28 | + double left = 0.0; |
| 29 | + double right = 1.0; |
| 30 | + while (left < right) { |
| 31 | + double mid = left + (right - left) / 2; |
| 32 | + vector<int> ans = { 0, 1 }; |
| 33 | + // mid 左边有多少个 |
| 34 | + int count = left_count(arr, mid, ans); |
| 35 | + if (count == k) // mid 左边正好有 k 个,即为ans |
| 36 | + return ans; |
| 37 | + else if (count < k) |
| 38 | + left = mid; |
| 39 | + else |
| 40 | + right = mid; |
| 41 | + } |
| 42 | + return { 0, 1 }; |
| 43 | + } |
| 44 | + |
| 45 | + |
| 46 | + int left_count(const vector<int>& arr, double mid, vector<int>& bound) { |
| 47 | + int count = 0; |
| 48 | + // 两层for循环仍可以优化 |
| 49 | + for (int j = 1; j < arr.size(); j++) { |
| 50 | + for (int i = 0; i < j; i++) { |
| 51 | + if ((double) arr[i] / arr[j] < mid) { |
| 52 | + count++; |
| 53 | + if (arr[i] * bound[1] > bound[0] * arr[j]) { |
| 54 | + bound[0] = arr[i]; |
| 55 | + bound[1] = arr[j]; |
| 56 | + } |
| 57 | + } else { |
| 58 | + break; |
| 59 | + } |
| 60 | + } |
| 61 | + } |
| 62 | + return count; |
| 63 | + } |
| 64 | +}; |
| 65 | +// @lc code=end |
| 66 | + |
0 commit comments