1. 程式人生 > >【Leetcode】378. Kth Smallest Element in a Sorted Matrix

【Leetcode】378. Kth Smallest Element in a Sorted Matrix

之前 prior return 例如 mat all 查找 row 所在

Question:

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.

Tips:

給定一個n*n的矩陣,矩陣內每行跟每列都是升序排列的,找到矩陣中第k小的元素,並返回。

解法:

思路1:

要找到第k小的數字,可以預先設定一個值mid=low+(high-low)/2;每次找到一個mid,然後求比它小的元素的個數,根據個數大於k還是小於k來二分。在尋找小於mid的元素個數的時候,可以從左下或者右上開始查找,例如從矩陣左下開始查找,當前數字>target就可以刪除該數字所在列的後面所有數字,row--。如果當前數字<target,表示該行中,該數字之前的所有數字均小於target,col++;ans+=row+1;

代碼1:

public int kthSmallest(int[][] matrix,int k){
        if(matrix==null ||matrix.length==0) return 0;
        int ans=0;
        int n=matrix.length;
        int low=matrix[0][0];
        int high=matrix[n-1][n-1];
        while(low<high){
            int mid=low+(low+high)/2;
            int count=binarysearch(matrix,mid);
            
if(count>k){ high=mid; }else low=mid+1; } return ans; } private int binarysearch(int[][] matrix, int target) { int ans=0; int len=matrix.length; int row=len-1;int col=0; while(row>=0 && col<len){ if(matrix[row][col]>target) row--; else{ col++; ans+=row; } } return ans; }

思路2:

尋找第k小或第k大的元素均可以使用堆來解決。本題要找到最小的第k個元素,可以使用最大堆來完成。堆的大小等於k是,堆的root即為所要求,

代碼2:

public int kthSmallest(int[][] matrix, int k) {
        // heap
        PriorityQueue<Integer> maxHeap = new PriorityQueue<>(k + 1, (a, b) -> b - a);
        
        for(int i = 0; i < matrix.length; i++) {
            for(int j = 0; j < matrix[0].length; j++) {
                maxHeap.offer(matrix[i][j]);
                if(maxHeap.size() > k) maxHeap.poll();
            }
        }
        
        return maxHeap.poll();
    }

【Leetcode】378. Kth Smallest Element in a Sorted Matrix