二分查找
区间长度为[mn, mx]
然后O(n) 求出 <= 每个mid的个数
和k比较
class Solution {
public:
int kthSmallest(vector<vector<int>>& v, int k) {
int len = v.size();
if(k <= 0 || len*len < k || len == 0)
return -1;
int mx = INT_MIN, mn = INT_MAX;
for(auto vv : v) {
for(auto vvv : vv) {
mx = max(mx, vvv);
mn = min(mn, vvv);
}
}
int ans = -1;
int l = mn, r = mx;
while(l <= r) {
int m = l + (r-l)/2;
if(count(v, m) >= k)
ans = m, r = m-1;
else
l = m+1;
}
return ans;
}
int count(vector<vector<int>>& v, int m) {
int len = v.size();
int i = len-1, j = 0;
int tot = 0;
while(i >=0 && j < len) {
if(v[i][j] > m)
i--;
else {
tot += i + 1;
j++;
}
}
return tot;
}
};
堆
建立一个堆,然后不断的pop k次.. 最后一次pop的就是了
注意cmp的写法
class Solution {
public:
struct cmp{
bool operator() (const pair<int,pair<int,int>> &a,
const pair<int,pair<int,int>> &b) {
return a.first > b.first;
}
};
int kthSmallest(vector<vector<int>>& v, int k) {
int len = v.size();
if(len == 0 || k <= 0 || len*len <k)
return -1;
priority_queue<pair<int,pair<int,int>>,vector<pair<int,pair<int,int>>>,
cmp> que;
for(int i=0; i<len; i++) {
que.push({v[i][0], {i,0}});
}
int x = k, ans = -1;
while(x --) {
ans = que.top().first;
int i = que.top().second.first;
int j = que.top().second.second;
que.pop();
if(j != len-1)
que.push({v[i][j+1], {i,j+1}});
}
return ans;
}
};