378. Kth Smallest Element in a Sorted Matrix

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.

Problem URL


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
  1. 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)

  1. 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;
    }
}

Review
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值