Leetcode 378. 有序矩阵中第 K 小的元素 二分查找

原题链接:Leetcode 378. 有序矩阵中第 K 小的元素

解题思路:

参考自博客:LeetCode题练习与总结:有序矩阵中第 K 小的元素--378

cpp 复制代码
class Solution {
public:
    int kthSmallest(vector<vector<int>>& matrix, int k) {
        int n=matrix.size();
        int l=matrix[0][0];
        int r=matrix[n-1][n-1];
        while(l<r){
            int mid=l+(r-l)/2;
            int j=n-1;
            int cnt=0;
            for(int i=0;i<n;i++){
                while(j>=0 && matrix[i][j]>mid){
                    j--;
                }
                cnt+=(j+1);
            }
            if(cnt<k){
                l=mid+1;
            }
            else{
                r=mid;
            }
        }
        return l;
    }
};

为什么left一定在矩阵中?

  • 循环过程中,矩阵中第k小的那个数始终在区间left, right

  • 循环过程中,left和right可能不是矩阵中的元素,但是left, right中某个元素 "在矩阵中" 且 "满足第k小"

  • 当right == left时,left, right中只有一个元素了(即left),所以此时left必然 "在矩阵中" 且

    "满足第k小"

此题的完整流程+过程演示:

cpp 复制代码
#include <iostream>
#include <vector>
using namespace std;

int kthSmallest(vector<vector<int>>& matrix, int k) {
    int n=matrix.size();
    int l=matrix[0][0];
    int r=matrix[n-1][n-1];
    int round=1;
    while(l<r){
        cout<<"第" <<round<<"次查找:"<<endl;
        cout<<"开始时:" <<endl;
        int mid=l+(r-l)/2;
        int j=n-1;
        int cnt=0;
        cout<<"left:"<<l<<endl;
        cout<<"right:"<<r<<endl;
        cout<<"mid:"<<mid<<endl;
        for(int i=0;i<n;i++){
            while(j>=0 && matrix[i][j]>mid){
                j--;
            }
            cnt+=(j+1);
        }
        if(cnt<k){
            l=mid+1;
        }
        else{
            r=mid;
        }
        round++;
        cout<<"找到" <<cnt<<"个小于等于mid的数"<<endl;
        cout<<"更新后:"<<endl;
        cout<<"left:"<<l<<endl;
        cout<<"right:"<<r<<endl;
        cout<<"------------------------------------------------------"<<endl;
    }
    return l;
}

int main()
{
    vector<vector<int>> mat;
    mat.push_back({1,5,9});
    mat.push_back({10,11,13});
    mat.push_back({12,13,15});
    int res=kthSmallest(mat, 8);
    cout<<res<<endl;
    return 0;
}
cpp 复制代码
第1次查找:
开始时:
left:1
right:15
mid:8
找到2个小于等于mid的数
更新后:
left:9
right:15
------------------------------------------------------
第2次查找:
开始时:
left:9
right:15
mid:12
找到6个小于等于mid的数
更新后:
left:13
right:15
------------------------------------------------------
第3次查找:
开始时:
left:13
right:15
mid:14
找到8个小于等于mid的数
更新后:
left:13
right:14
------------------------------------------------------
第4次查找:
开始时:
left:13
right:14
mid:13
找到8个小于等于mid的数
更新后:
left:13
right:13
------------------------------------------------------
13
相关推荐
JieE21218 小时前
LeetCode 56. 合并区间|超清晰 JS 图解思路,面试高频区间题
javascript·算法·面试
Jack201 天前
HarmonyOS开发中错误处理策略:网络异常统一处理
算法
小小杨树1 天前
读懂色彩:拍照调色不再难
算法·计算机视觉·配色
JieE2122 天前
LeetCode 226. 翻转二叉树|JS 递归超详细拆解,二叉树入门经典题
javascript·算法
JieE2122 天前
LeetCode 104. 二叉树的最大深度|递归思路超详细拆解
javascript·算法
vivo互联网技术2 天前
CVPR 2026 | 全新强化学习框架 BeautyGRPO:重塑真实人像
算法·大模型·cvpr·影像
Darling噜啦啦2 天前
列表转树算法深度解析:从 Map 到 Reduce 的两种实现,面试高频考点
数据结构·算法·面试
用户497863050732 天前
(一)小红的数组操作
算法·编程语言
怕浪猫2 天前
Electron 系列文章封面图
算法·架构·前端框架