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
相关推荐
叩码以求索1 小时前
浅谈:前序遍历反转法求解N叉树的后序遍历
算法
北风toto2 小时前
中缀、前缀、后缀表达式
算法·软件设计师
听取WA声一片(无恶意)2 小时前
CSP-J/CSP-S 深度优先搜索(DFS)完全讲义
c++·算法·深度优先
招财小梗3 小时前
AI矩阵获客,品牌连锁落地方案揭秘
大数据·人工智能·矩阵
码流怪侠3 小时前
2026年8月GitHub热榜深度拆解:Agent Skills席卷开源圈,一个“技能包“收割5万星
算法·程序员·github
hold?fish:palm3 小时前
30 两两交换链表中的节点
数据结构·算法·链表
Nil2083 小时前
leetcode 98验证二叉搜索树
算法·leetcode·职场和发展
不正经学生3 小时前
C语言结构体:自定义数据类型,让变量打包出行
java·c语言·开发语言·数据结构·算法
cxr8284 小时前
数学的本质:关系、模式与不变量的结构世界
人工智能·算法·机器学习
初夏睡觉5 小时前
原创题目 - 空壳恋爱
c++·算法·dp·oi·信息学·原创题目·值得挑战的题目