378. Kth Smallest Element in a Sorted Matrix【leetcode解题报告】

11 篇文章 0 订阅
11 篇文章 0 订阅

题目

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.

代码

思路1

分治法,初始化left为最小值,right为最大值,进过二分left和right最终会相等,并且会变成数组中第k小的数字。

stl::upper_bound学习链接

class Solution
{
public:
    int kthSmallest(vector<vector<int>>& matrix, int k)
    {
        int n = matrix.size();
        int le = matrix[0][0], ri = matrix[n - 1][n - 1];
        int mid = 0;
        while (le < ri) //O(n)
        {
            //mid为中位数
            mid = (le+ri)/2;
            int num = 0;
            //遍历矩阵,O(nlgn)
            for (int i = 0; i < n; i++)
            {
                //O(lgn)
                //stl模板学习:https://www.cnblogs.com/cobbliu/archive/2012/05/21/2512249.html
                //upper_bound(A.first,A.last,val) 返回一个非递减序列[first, last)中第一个大于val的位置。
                //int pos = upper_bound(matrix[i].begin(), matrix[i].end(), mid) - matrix[i].begin();
                //num += pos;
                //直接遍历是O(n*n)
                int j=0;
                while(j<matrix[i].size() && matrix[i][j]<=mid){
                    ++j;
                    ++num;
                }
            }
            //不能用这句话跳出循环,因为mid不一定在矩阵中
            // if(num == k){
            //     return le;
            // }
            if (num < k) le = mid + 1;
            else ri = mid;
        }
        return le;
    }
};
进一步优化思路1

在按照mid值搜索countnum的时候,可以不用二分法,而是利用有序数组的性质,从数组的左下角开始计算countnum的值,若小于mid则该位以上的数均小于mid,并向右移一位,否则向上移动一位。

思路2:

构造最大堆,遍历数组放入最大堆,然后依次弹出最大堆堆顶元素,判断堆内大小,若size==k则结束,否则继续弹出堆顶元素。O(nlgn)

public:
    int kthSmallest(vector<vector<int>>& matrix, int k)
    {
        int n = matrix.size();
        if(n==0) return 0;
        int m=matrix[0].size();
        priority_queue<int> max_heap;
        for(int i=0;i<n;++i){
            for(int j=0;j<m;++j){
                max_heap.push(matrix[i][j]);
            }
        }
        int res=0;
        while(!max_heap.empty()){
            if(max_heap.size()==k){
                res = max_heap.top();
                break;
            }
            max_heap.pop();
        }
        return res;

    }
思路3

优先队列

class Solution {
public:
struct compare
{
    bool operator()(const pair<int,pair<int, int> >& a, const pair<int,pair<int, int> >& b)
    {
        return a.first>b.first;
    }
};
    int kthSmallest(vector<vector<int>>& arr, int k) {

        int n=arr.size(),m=arr[0].size();

        priority_queue< pair<int,pair<int, int> >, vector<pair<int, pair<int, int> > >, compare > p;

        for(int i=0;i<n;i++)
        p.push(make_pair(arr[i][0],make_pair(i,0)));

        int x=k,ans;
        while(x--)
        {
            int e=p.top().first;
            int i=p.top().second.first;
            int j=p.top().second.second;
            ans=e;
            p.pop();
            if(j!=m-1)
            p.push(make_pair(arr[i][j+1],make_pair(i,j+1)));
        }
        return ans;

    }
};

解题链接:https://leetcode.com/problems/kth-smallest-element-in-a-sorted-matrix/discuss/85173/Share-my-thoughts-and-Clean-Java-Code

类似题:https://leetcode.com/problems/find-k-pairs-with-smallest-sums/description/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值