那么这道题就可以转化为Kth smallest element in sorted matrix的题目。需要注意的是我们这里搜索范围是[0, 1],而且是小数,我们搜索的mid不一定是在array里的。所以我们需要对二分做一些改良:
- 对于mid,我们仍然是统计小于等于mid的有多少个,这个可以再n + n = O(n)的时间内完成
- 同时我们需要记录小于等于mid在array当中存在的最大分数是什么,因为mid不一定在array中
- 假设小于等于mid的有d个
- 如果d < k,那么mid一定不是结果,lo = mid
- 如果d >= k那么mid有可能是结果,因为第k大的数可能有重复的,导致统计之后可能大于k。所以我们需要先存下来,之后继续更新可能的结果。
时间复杂度O(N * log W), W为搜索的宽度,这里为(hi - lo) / 1e-9,代码如下:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Solution { | |
public: | |
vector<int> kthSmallestPrimeFraction(vector<int>& A, int K) { | |
int len = A.size(); | |
double lo = 0, hi = 1.0; | |
vector<int> ret(2); | |
while (hi - lo > 1e-9) | |
{ | |
double mid = lo + (hi - lo) / 2.0; | |
auto res = count(A, mid); | |
if (res[0] < K)lo = mid; | |
else | |
{ | |
ret[0] = res[1]; | |
ret[1] = res[2]; | |
hi = mid; | |
} | |
} | |
return ret; | |
} | |
private: | |
vector<int> count(vector<int>& A, double target) | |
{ | |
int len = A.size(), i = len - 1; | |
vector<int> res(3, 0); | |
for (int j = len - 1; j >= 0; --j) | |
{ | |
while (i >= 0 && target * A[j] < A[i]) | |
--i; | |
res[0] += i + 1; | |
if (!res[2] || (i >= 0 && static_cast<long>(A[i]) * res[2] > static_cast<long>(res[1]) * A[j])) | |
{ | |
res[1] = A[i]; | |
res[2] = A[j]; | |
} | |
} | |
return res; | |
} | |
}; |
No comments:
Post a Comment