• 378. Kth Smallest Element in a Sorted Matrix(大顶堆、小顶堆)


    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.

    class Solution {
    public:
        //一般在无序数组中求第k大的数,利用堆排序。
        //priority_queue< int,vector<int>,greater<int> > 小顶堆
        //priority_queue< int,vector<int>,less<int> > 默认大顶堆
        int kthSmallest(vector<vector<int>>& matrix, int k) {
            vector<int> m;
            for(int i=0;i<matrix.size();i++){
                for(int j=0;j<matrix[i].size();j++){
                    m.push_back(matrix[i][j]);
                }
            }
            priority_queue< int,vector<int>,less<int> > p;
            for(int i=0;i<m.size();i++){
                if(p.size()<k){
                    p.push(m[i]);
                }else{
                    if(p.top() > m[i]){
                        p.pop();
                        p.push(m[i]);
                    }
                }
            }
            return p.top();
        }
    };

    //二分查找

    //这个二分不好想。

    //left = mid+1; 理解左边个数小于k个,就得慢慢找到下一个left值,而且left值必定在矩阵中,左边个数才会多一个。否则会一直加1.
    //right = mid; 理解当左边的个数正好是k个,下面循环一直到left == right,此时返回left.
    //当左边多余k个,只有left=right,mid才会再之后的循环中保持不变。否则mid肯定会一直变小。
    class Solution {
    public:
        //二分一般有两种:1、按照下标进行二分,例如数组有序 https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/
        //或者数组无序,要找满足条件的元素个数,以数组元素大小二分:https://leetcode.com/submissions/detail/134554396/
        int kthSmallest(vector<vector<int>>& matrix, int k) {
            //这题借鉴第二种二分思路,找k个数满足条件
            int row = matrix.size();
            int col = matrix[0].size();
            int left=matrix[0][0],right=matrix[row-1][col-1];
            while(left<right){
                int mid = left+(right-left)/2;
                int count=0,j=col-1;
                //计算小于中间数的个数。
                for(int i = 0; i < row; i++) {
                    while(j >= 0 && matrix[i][j] > mid) j--;
                    count += (j + 1);
                }
                if(count < k){
                    left = mid+1;
                }
                else {
                    right = mid;
                }
            }
            return left;
        }
    };
  • 相关阅读:
    Mybatis动态数据源
    [Java基础]判断字符串指定字符类型
    [Java基础]让Map value自增
    (转载)UTF-8占几个字符
    JVM程序计数器
    Mybatis异常总结
    通过类对象来获取类中的属性,方法,构造器
    主动引用和被动引用
    ClassLoader类加载器浅见
    反射----获取class对象的五种方法
  • 原文地址:https://www.cnblogs.com/wsw-seu/p/13910238.html
Copyright © 2020-2023  润新知