给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第k小的元素。
请注意,它是排序后的第k小元素,而不是第k个元素。
示例:
matrix = [ [ 1, 5, 9], [10, 11, 13], [12, 13, 15] ], k = 8, 返回 13。
说明:
你可以假设 k 的值永远是有效的, 1 ≤ k ≤ n2 。
这里的思路是最外面一个二分搜索一个元素X, 使得小于X的元素的个数正好为k-1,而小于等于X的元素个数恰好是k,那么这个X一定就是答案
在二分搜所问题中,要解决一个子问题,这个子问题是统计二维矩阵中小于等于X的元素个数,这个要充分利用这个二维矩阵的特点,从左下角开始搜索,总的时间复杂度是O(N)
所以最后这个问题的时间复杂度是O(NlogN)
class Solution {
public:
int kthSmallest(vector<vector<int>>& matrix, int k) {
int row = matrix.size(), col = matrix[0].size();
int left = matrix[0][0], right = matrix[row-1][col-1];
while(left<=right){
int mid = left + (right-left)/2;
if(check(matrix,k,mid)) right=mid-1;
else left=mid+1;
}
return left;
}
bool check(vector<vector<int>>& matrix, int k, int X){
// 比较小于等于X的元素与k的关系
int i = matrix.size()-1;
int j = 0; // 每次从左下角开始搜索
int K = 0;
while(i>=0 && j <matrix.size()){
if(matrix[i][j]>X) i--;
else{
K +=(i+1); // 如果当前元素小于X, 那么前面i个元素都小于X
j++;
}
}
return K>=k;
}
};