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
相关推荐
m0_7369191011 分钟前
模板元编程性能分析
开发语言·c++·算法
pen-ai18 分钟前
【YOLO系列】 YOLOv1 目标检测算法原理详解
算法·yolo·目标检测
2301_7657031439 分钟前
C++中的职责链模式实战
开发语言·c++·算法
StandbyTime1 小时前
《算法笔记》学习记录-第一章
c++·算法·算法笔记
近津薪荼1 小时前
优选算法——双指针8(单调性)
数据结构·c++·学习·算法
格林威1 小时前
Baumer相机铆钉安装状态检测:判断铆接是否到位的 5 个核心算法,附 OpenCV+Halcon 的实战代码!
人工智能·opencv·算法·计算机视觉·视觉检测·工业相机·堡盟相机
星空露珠1 小时前
速算24点检测生成核心lua
开发语言·数据库·算法·游戏·lua
happygrilclh2 小时前
高压高频电源的pid算法
算法
格林威2 小时前
Baumer相机铸件气孔与缩松识别:提升铸造良品率的 6 个核心算法,附 OpenCV+Halcon 实战代码!
人工智能·opencv·算法·安全·计算机视觉·堡盟相机·baumer相机
葫三生2 小时前
存在之思:三生原理与现象学对话可能?
数据库·人工智能·神经网络·算法·区块链