378. 有序矩阵中第K小的元素(排序或者二分)

378. 有序矩阵中第K小的元素

  • 第一种方法:将二维矩阵中的数存起来,然后排序输出第k个,耗时较多

class Solution {
public:
    int kthSmallest(vector<vector<int>>& matrix, int k) {
        vector<int>v;
        for(int i=0;i<matrix.size();i++)
        {
            for(int j=0;j<matrix[0].size();j++)
            {
                v.push_back(matrix[i][j]);
            }
        }
        sort(v.begin(),v.end());
        return v[k-1];
    }
};
  • 第二种方法:利用二分,左上角的数最小,右下角的数最大,取个mid,然后在矩阵中找出小于等于mid的数cnt

  1. 如果cnt<k,则说明小于等于mid的数的个数不足k个,那么令左端为mid+1,向右找,直到找到小于等于mid的数为k个,那么此时的L就是答案;

  2. 当cnt>=k的时候,说明小于等于mid的数已经超过k了,mid比我们要求的数肯定大,那么将右端点为mid即可,在左边查找。

  3. 至于怎么找矩阵中小于等于mid的个数,我们可以从矩阵左下角开始找,当该位置的数<=mid,此时cnt+=i+1,

    就是该列第i行的上面的所有的元素都小于等于mid,累加即可,同时列指针j++;

    如果该位置的数大于了mid,那么只要将行指针向上i--即可。复杂度比第一种方法小得多,耗时短。

class Solution {
public:
   bool check(vector<vector<int>>& matrix,int mid,int k)
   {
        int n=matrix.size();
        int i=n-1,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 L=matrix[0][0],R=matrix[n-1][n-1];
       while(L<R)
       {
           int mid=(L+R)>>1;
           if(check(matrix,mid,k))
               L=mid+1;
           else
               R=mid;
       }
       return L;
   }
};
posted @ 2020-06-26 21:06  branna  阅读(205)  评论(0编辑  收藏  举报