LeetCode Solutions
786. K-th Smallest Prime Fraction
Time: $O(n\log \max^2(A))$ Space: $O(1)$
class Solution {
public:
vector<int> kthSmallestPrimeFraction(vector<int>& A, int K) {
const int n = A.size();
double l = 0.0;
double r = 1.0;
while (l < r) {
const double m = (l + r) / 2.0;
int fractionsNoGreaterThanM = 0;
int p = 0;
int q = 1;
// For each index i, find the first index j s.t. A[i] / A[j] <= m,
// So fractionsNoGreaterThanM for index i will be n - j
for (int i = 0, j = 1; i < n; ++i) {
while (j < n && A[i] > m * A[j])
++j;
if (j == n)
break;
fractionsNoGreaterThanM += n - j;
if (p * A[j] < q * A[i]) {
p = A[i];
q = A[j];
}
}
if (fractionsNoGreaterThanM == K)
return {p, q};
if (fractionsNoGreaterThanM > K)
r = m;
else
l = m;
}
throw;
}
};
class Solution {
public int[] kthSmallestPrimeFraction(int[] A, int K) {
final int n = A.length;
double l = 0.0;
double r = 1.0;
while (l < r) {
final double m = (l + r) / 2.0;
int fractionsNoGreaterThanM = 0;
int p = 0;
int q = 1;
// For each index i, find the first index j s.t. A[i] / A[j] <= m,
// So fractionsNoGreaterThanM for index i will be n - j
for (int i = 0, j = 1; i < n; ++i) {
while (j < n && A[i] > m * A[j])
++j;
if (j == n)
break;
fractionsNoGreaterThanM += n - j;
if (p * A[j] < q * A[i]) {
p = A[i];
q = A[j];
}
}
if (fractionsNoGreaterThanM == K)
return new int[] {p, q};
if (fractionsNoGreaterThanM > K)
r = m;
else
l = m;
}
throw new IllegalArgumentException();
}
}
class Solution:
def kthSmallestPrimeFraction(self, A: List[int], K: int) -> List[int]:
n = len(A)
ans = [0, 1]
l = 0
r = 1
while True:
m = (l + r) / 2
ans[0] = 0
count = 0
j = 1
for i in range(n):
while j < n and A[i] > m * A[j]:
j += 1
count += n - j
if j == n:
break
if ans[0] * A[j] < ans[1] * A[i]:
ans[0] = A[i]
ans[1] = A[j]
if count < K:
l = m
elif count > K:
r = m
else:
return ans