トピック
各行と各列の要素が昇順で並べ替えられているnxn行列が与えられた場合、行列内でk番目に小さい要素を見つけます。
これは、ソート後のk番目に小さい要素であり、k番目の異なる要素ではないことに注意してください。リンク
アイデア
2点。。本当に意外。。
- マトリックスの性質上、各要素の左上隅にあるすべての要素はそれ以下であるため、マトリックスの左下隅からトラバースし
O(n)
て、特定の要素以下のすべての数値を時間内に見つけることができます。- 分割,,この間隔の値が2つに分割されているように、最小の要素は、この間隔内でなければなりません。
left = matrix[0][0], right = matrix[n - 1][n - 1]
k
left
境界は以下mid
の数で決定されるため、最後にマトリックスに含める必要があるのはなぜですか。境界は縮小されますk
が、常にこの境界にあり、要素はすべて整数です。1つの要素に縮小さ即left == right
れると、k
最小の要素になります。。
class Solution {
public int kthSmallest(int[][] matrix, int k) {
int n = matrix.length;
int left = matrix[0][0];
int right = matrix[n - 1][n - 1];
while(left < right){
int mid = left + (right - left) / 2;
if(helper(matrix, k, mid)){
//严格小于的一定不是解
left = mid + 1;
}else{
right = mid;
}
}
return left;
}
boolean helper(int[][]matrix, int k, int mid){
int n = matrix.length;
int i = n - 1, j = 0;
int count = 0;
while(i >=0 && j < n){
if(matrix[i][j] <= mid){
//第j列一共有i+1个元素小于等于mid
count += i + 1;
j++;
}else{
i--;
}
}
return count < k;
}
}