leetcode378. The Kth Smallest Element in an Ordered Matrix

378. The Kth Smallest Element in an Ordered Matrix

Given an nxn matrix, where each row and column is sorted in ascending order, find the kth smallest element in the matrix.
Note that it is the k-th smallest element after sorting, not the k-th distinct element.

You have to find a solution with better memory complexity than O(n2).

Example 1:

Input: matrix = [[1,5,9],[10,11,13],[12,13,15]], k = 8
Output: 13 Explanation: The elements in the matrix are
[1,5,9, 10,11,12,13,13,15], the 8th smallest element is 13

Example 2:

Input: matrix = [[-5]], k = 1 Output: -5

hint:

n == matrix.length n == matrix[i].length 1 <= n <= 300
-109 <= matrix[i][j] <= 109 The title data guarantees that all rows and columns in the matrix are non-decreasing order 1 <= k <= n2

Advanced:

Can you solve this problem with a constant memory (i.e. O(1) memory complexity)? Can you solve this problem in O(n)
time complexity? This method may be too advanced for interviews , but you will find it interesting to read this paper.

Analysis
1, according to the value range of matrix elements, left=1 , right=16 , mid=8, it can be found that all items greater than 8 are in the lower right corner, and those less than 8 are in the upper left corner, so the number of left and right sides can be divided into two.
2, if less than 8 numbers nums<=k, then right=mid, otherwise, left=mid+1;
insert image description here
code

class Solution {
    
    
public:
    bool check(vector<vector<int>>& matrix, int mid,int k,int n){
    
    
        int i=n-1;
        int j=0;
        int cnt=0;
        while(i>=0&&j<n){
    
    
            if(matrix[i][j]<=mid){
    
    
                cnt+=i+1;
                j++;
            }
            else
                i--;
        }
        return cnt>=k;
    }
    int kthSmallest(vector<vector<int>>& matrix, int k) {
    
    
        int n=matrix.size();
        int left=matrix[0][0];
        int right=matrix[n-1][n-1];
        while(left<right){
    
    
            int mid=(left+right)>>1;
            // 如果check返回值为true,结果应该<=mid,因此这里应该保留mid
            if(check(matrix,mid,k,n)){
    
    
                right=mid;
            }
            else{
    
    
                left = mid + 1;
            }
        }
        return left;
    }
};

Image source, title source: leetcode378

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324518963&siteId=291194637