Description
Given a n x n matrix where each of the rows and columns are sorted in ascending order, find the kth smallest element in the matrix.
Note that it is the kth smallest element in the sorted order, not the kth distinct element.
Example:
matrix = [
[ 1, 5, 9],
[10, 11, 13],
[12, 13, 15]
],
k = 8,
return 13.
Note:
You may assume k is always valid, 1 ≤ k ≤ n2.
Solution
给一个二维数组,每行从左到右升序,每列从上到下升序,求第k小的元素。
Using a priority queue to keep the sequence of expanded element. The pq stores a int[] which denotes the position and value of it. Poll k - 1 times to get the kth element to peek.
Code
- heap
class Solution {
public int kthSmallest(int[][] matrix, int k) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0){
return 0;
}
int m = matrix.length;
int n = matrix[0].length;
PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[2] - b[2]);
//add first row to pq
for (int i = 0; i < n; i++){
pq.offer(new int[]{0, i, matrix[0][i]});
}
//poll out k - 1 times to move the kth to peek
for (int i = 0; i < k - 1; i++){
int[] element = pq.poll();
if (element[0] + 1 < m){
pq.offer(new int[]{element[0] + 1, element[1], matrix[element[0] + 1][element[1]]});
}
}
return pq.peek()[2];
}
}
Time Complexity: O(klogm)
Space Complexity: O(m)
- binary search
It is a little different than ordinary one.
class Solution {
public int kthSmallest(int[][] matrix, int k) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0){
return 0;
}
int m = matrix.length;
int n = matrix[0].length;
//perform binary search using the min and max element
int low = matrix[0][0], high = matrix[m - 1][n - 1];
while (low < high){
int mid = low + (high - low) / 2;
int count = 0, j = n - 1;
//for each row, from back to head, count how many element less than mid in each row.
//because in next row, matrix[i+1][j] must bigger than matrix[i][j], j could reuse.
for (int i = 0; i < m; i++){
while (j >= 0 && matrix[i][j] > mid){
j--;
}
count += (j + 1);
if (j == -1){
break;
}
}
//find the exact value;
if (count < k){
low = mid + 1;
}
else{
high = mid;
}
}
return low;
}
}