Note:
You may assume k is always valid, 1 ≤ k ≤ n2.
Solution
1. O(N2logK) using max heap
class Solution {
public:
int kthSmallest(vector<vector<int>>& matrix, int k){
priority_queue<int> max_heap;
for (const auto &row: matrix) {
for (const auto &e: row) {
if (max_heap.size() < k) {
max_heap.push(e);
continue;
}
if (e < max_heap.top()) {
max_heap.pop();
max_heap.push(e);
}
}
}
return max_heap.top();
}
};
2. O(MlogM)(M=max(K,N) using min heap
class Solution {
public:
typedef pair<int, int> coord;
int kthSmallest(vector<vector<int>>& matrix, int k){
const int n = matrix.size();
auto comparator = [&matrix](const auto &a, const auto &b) {
return matrix[a.first][a.second] > matrix[b.first][b.second];
};
priority_queue<coord, vector<coord>, decltype(comparator)> min_heap(comparator);
for (int i = 0; i < n; ++i) min_heap.push({i, 0});
int kth_smallest, row, col;
do {
row = min_heap.top().first;
col = min_heap.top().second;
kth_smallest = matrix[row][col];
min_heap.pop();
if (col + 1 < n) min_heap.push({row, col + 1});
} while (--k > 0);
return kth_smallest;
}
};
3. O(NlogM)(M=max−min) using binary search
class Solution {
public:
inline int countLowerBound(vector<vector<int>>& matrix, int target) {
int count = 0;
int row = 0, col = matrix.size() - 1;
do {
while (col >= 0 && matrix[row][col] > target) --col;
count += col + 1;
} while (++row < matrix.size());
return count;
}
int kthSmallest(vector<vector<int>>& matrix, int k){
int begin = matrix.front().front();
int end = matrix.back().back();
while (begin < end) {
int mid = begin + (end - begin) / 2;
int count = countLowerBound(matrix, mid);
if (count < k) begin = mid + 1;
else end = mid;
}
return begin;
}
};