【刷题】leetcode378. 有序矩阵中第K小的元素(二分查找)

给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第 k 小的元素。
请注意,它是排序后的第 k 小元素,而不是第 k 个不同的元素。
示例:
matrix = [
[ 1, 5, 9],
[10, 11, 13],
[12, 13, 15]
],
k = 8,
返回 13。

分析:
i)利用矩阵的特点:其中每行和每列元素均按升序排序。
图片描述
由这个特点可以得到几个性质:
1.A是四个元素中最小值,D是最大值。
2.如果C>n,则D一定大于n,此时如果A<n,则B小于n。也就是说,当我们判断完C大于n后,想要找到下一个小于等于n的元素,应该先判断A的情况;同理,判断完C小于等于n后,应该先判断D的情况。
3.C小于等于n时,C所在的那一列,C以上的元素都是小于等于n的。

根据上面的总结从一个矩阵的左下角元素开始,按照2的规则:
如果当前元素≤n,则把这一列中到当前元素的个数进行累加,然后判断右边的元素;
如果当前元素>n,就判断上边的元素;

一直遍历到右上角,就可以得到矩阵中所有小于等于n的元素个数。

ii)利用小于等于mid的元素个数进行二分查找
把矩阵想象成下图的序列:最小值和最大值是确定的,中间不是具体的元素,而是一个范围。
在这里插入图片描述
当序列中小于等于mid的元素个数小于k时,则第k小的元素肯定在[mid+1,right]中找到;
当序列中小于等于mid的元素个数大于等于k时,则第k小的元素肯定在[left,mid]中找到;

在二分查找中需要注意“=”到底归在哪边的问题:
当left=i,right=i+1时,mid=left
①num<mid, right = mid-1;
num≥mid, left=mid。
这时,如果num<mid, right= left-1,两个边界不会相交,无法得到正确结果;如果num≥mid,left= left,会陷入死循环。
②num≤mid, right = mid;
num>mid, left=mid+1。
这时,如果num<mid, right= left;如果num≥mid,left= right,无论是哪种情况,left和right都会相交。

class Solution {
public:
    
    int kthSmallest(vector<vector<int>>& matrix, int k) {
        int left = matrix[0][0],right = matrix[matrix.size()-1][matrix[0].size()-1];
        int mid;
        while(left<right){
            mid = left+(right-left)/2;//防止溢出
            if(lessThanK(matrix,k,mid))
                left = mid+1;
            else right= mid;
        }
        return left;
    }
    bool lessThanK(vector<vector<int>>& matrix, int k,int mid){
        int row = matrix.size()-1,col = 0;
        int sum = 0;
        while(row>=0&&col<matrix[0].size()){
            if(matrix[row][col]<=mid){
                sum+= row+1;
                col++;
            }else row--;
        }
        if(sum<k)return true;
        else return false;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值