题目
给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第k小的元素。
请注意,它是排序后的第k小元素,而不是第k个元素。
思路
直接求解矩阵中的第8小元素很难,我们可以用二分法设定一个值mid,查看mid值是否是矩阵第8小元素。
具体思路为:
1.首先设置mid的初值为矩阵matrix,最后一个数和第一个数的平均值。
2.统计矩阵中每一行小于mid值的个数之和。若该值小于8,记录当前mid,L = mid + 1,并更新mid;若该值大于8,R = mid - 1。
3.重复上述搜索,直至L和R不满足L <= R,此时的mid值即为所求。
时间复杂度为O(nlognlogn)
class Solution {
public static boolean guess(int[][] matrix, int g, int n, int k){
int sum = 0;
for(int i = 0; i < n; i++){
int L = 0;
int R = n - 1;
int ans = 0;
while (L <= R){
int mid = L + (R - L)/2;
//若某一行值小于g,则应该是最后一个元素的下标 + 1.
if(matrix[i][mid] < g){
ans = mid + 1;
L = mid + 1;
}else {
R = mid - 1;
}
}
sum += ans;
}
return k > sum;
}
public static int kthSmallest(int[][] matrix, int k) {
int n = matrix.length;
int L = matrix[0][0];
int R = matrix[n - 1][n - 1];
int ans = 0;
while (L <= R){
int mid = L + (R - L )/2;
if(guess(matrix, mid, n, k)){
ans = mid;
L = mid + 1;
}else {
R = mid - 1;
}
}
return ans;
}
}
reference: