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
相关推荐
旧时光巷6 分钟前
【机器学习-2】 | 决策树算法基础/信息熵
算法·决策树·机器学习·id3算法·信息熵·c4.5算法
落了一地秋34 分钟前
4.5 优化器中常见的梯度下降算法
人工智能·算法·机器学习
前端伪大叔40 分钟前
第 5 篇:策略参数怎么调优?Freqtrade hyperopt 快速入门
算法·代码规范
Code季风41 分钟前
深入理解令牌桶算法:实现分布式系统高效限流的秘籍
java·算法·微服务
KyollBM1 小时前
【Luogu】每日一题——Day15. P1144 最短路计数 (记忆化搜索 + 图论 + 最短路)
算法·图论
一百天成为python专家1 小时前
K-近邻算法
数据结构·python·算法·pandas·近邻算法·ipython·python3.11
满分观察网友z1 小时前
告别烦人的“三连发”:我的智能评论系统过滤之旅(1957. 删除字符使字符串变好)
算法
小新学习屋1 小时前
《剑指offer》-数据结构篇-哈希表/数组/矩阵/字符串
数据结构·leetcode·哈希表
满分观察网友z1 小时前
滑动窗口下的极限挑战:我在实时数据流中挖掘最大价值分(1695. 删除子数组的最大得分)
算法
PerfumerKarma2 小时前
【WebGPU学习杂记】数学基础拾遗(2)变换矩阵中的齐次坐标推导与几何理解
学习·线性代数·矩阵