public class Solution {
public int kthSmallest(int[][] matrix, int k) {
int n = matrix.length;
int low = matrix[0][0];
int high = matrix[n-1][n-1]; // 最大最小值
while(low <= high){
int mid = low + (high-low)/2; // 这里 mid是 value, 不是 index
int count = countEqualLess(matrix, mid); // count that <= mid 的值
// if(count == k) {return mid;} // 这里要注意不能这样用, 因为mid不一定是在 matrix里面的值 !!!!
// example, 如果是 1 2 2 3, K = 2: mid=2 -> count=3 -> high=1/mid=1 -> count=1 -> low=2>high=1, return low=2 就对了
// example, 如果是 1 2 2 3. K =1 : mid=2 -> count=3 ->high=1/mid=1 -> count=1 -> high=0<low=1, return low=1 就对了
if(count < k){ // 不够, 说明还要更大,
low = mid + 1;
}
else{ // 超过了, 说明要小
high = mid - 1;
}
}
return low; // return的按照上面 example思路来
}
public int countEqualLess(int[][]matrix, int value){
// 仿照 No.240, 从左下角开始
int n = matrix.length;
int rowIndex = n-1;
int colIndex = 0;
int count = 0;
while(rowIndex >= 0 && colIndex <= n-1){
if(matrix[rowIndex][colIndex] > value){ //大了的话往上移动 rowIndex
rowIndex--;
}
else{ // 如果小于等于, 那么说明当前点以及这点上面这一列的点都是符合 <= value 的, 加上这些点, 然后往右移动试试
count += (rowIndex+1); // 这个主意 rowIndex 从 0 开始, 所以计算个数的时候是 rowIndex + 1 !!!!!
colIndex++;
}
}
return count;
}
}
class Solution {
public int kthSmallest(int[][] matrix, int k) {
if (matrix == null || matrix.length < 1 || matrix[0].length < 1) return -1;
int m = matrix.length, n = matrix[0].length;
int low = matrix[0][0], high = matrix[m - 1][n - 1];
while (low <= high) {
int mid = low + (high - low) / 2;
int cnt = countEqualLess(matrix, mid);
if (cnt < k) {
low = mid + 1;
} else {
high = mid - 1;
}
}
return low;
}
private int countEqualLess(int[][] matrix, int val) {
int m = matrix.length, n = matrix[0].length;
int col = n - 1, row = 0;
int count = 0;
while (row < m && col >= 0) {
int cur = matrix[row][col];
if (cur <= val) {
count += col + 1;
row++;
} else {
col--;
}
}
return count;
}
}
class Solution {
public int kthSmallest(int[][] matrix, int k) {
if (matrix == null || matrix.length < 1) return 0;
int row = matrix.length, col = matrix[0].length;
// {val, curRow, curCol}
PriorityQueue<int[]> q = new PriorityQueue<>(new Comparator<int[]>(){
public int compare(int[] a, int[] b) {
return a[0] - b[0];
}
});
for (int i = 0; i < row; i++) {
q.offer(new int[] {matrix[i][0], i, 0});
}
int res = 0;
for(int i = 0; i < k && !q.isEmpty(); i++) {
int[] cur = q.poll();
int curRow = cur[1], curCol = cur[2];
res = cur[0];
if (++curCol < col) {
q.offer(new int[] {matrix[curRow][curCol], curRow, curCol});
}
}
return res;
}
}