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

题目

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/

猜你喜欢

转载自blog.csdn.net/tan_change/article/details/80139922