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
-
如果cnt<k,则说明小于等于mid的数的个数不足k个,那么令左端为mid+1,向右找,直到找到小于等于mid的数为k个,那么此时的L就是答案;
-
当cnt>=k的时候,说明小于等于mid的数已经超过k了,mid比我们要求的数肯定大,那么将右端点为mid即可,在左边查找。
-
至于怎么找矩阵中小于等于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;
}
};