news 2026/4/23 13:13:10

LeetCode 378 有序矩阵中第 K 小的元素

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LeetCode 378 有序矩阵中第 K 小的元素


文章目录

    • 摘要
    • 描述
    • 题解答案
    • 题解代码分析
      • 为什么这是“二分答案”的题
      • 统计 ≤ mid 的元素个数
      • Swift 可运行 Demo 代码
      • 代码拆解说明
        • 1. 为什么 `left` 和 `right` 这样初始化
        • 2. `count < k` 为什么要 `left = mid + 1`
        • 3. 为什么最后直接返回 `left`
    • 示例测试及结果
    • 时间复杂度
    • 空间复杂度
    • 总结

摘要

LeetCode 378「有序矩阵中第 K 小的元素」是一道非常容易被写“重”的题

很多人第一反应是:

既然矩阵是有序的,那我全部摊平成数组,再排序不就好了?

没错,能过,但空间复杂度直接炸到 O(n²),而题目明确告诉你:

你必须用更省内存的方式。

这道题真正考的不是排序,而是你有没有意识到:
“答案本身也是有序的,可以用二分去猜。”

这篇文章会重点讲清楚:

  • 为什么这是一个“对值域做二分”的问题
  • 为什么不需要真的把第 k 个元素找出来
  • Swift 下如何写出一个稳定、易读的实现

描述

题目给你一个n x n的矩阵matrix,并保证:

  • 每一行是升序
  • 每一列也是升序

注意这里有一个很重要的点:

它不是整体排序后的第 k 个“不同元素”,
而是排序后的位置第 k 个元素

比如:

[1,5,9, 10,11,13, 12,13,15]

展开后是:

[1,5,9,10,11,12,13,13,15]

第 8 个元素是13,而不是跳过重复。

题解答案

这道题最主流、也最稳妥的解法是:

对值域做二分查找 + 利用矩阵有序性统计 ≤ mid 的元素个数

核心思路一句话总结:

  • 矩阵是有序的
  • 第 k 小的值,一定在[最小值, 最大值]这个区间里
  • 我们不关心它在哪,只关心“小于等于某个值的数有多少个”

题解代码分析

为什么这是“二分答案”的题

很多人卡在一个误区里:

二分不是只能用在数组索引上吗?

其实不是。
只要答案满足单调性,就能二分。

在这道题中:

  • 值越小

    • ≤ 这个值的元素数量越少
  • 值越大

    • ≤ 这个值的元素数量越多

这是一个天然的单调关系。

统计 ≤ mid 的元素个数

这是整道题最关键的地方。

因为矩阵行列都有序,我们可以这样做:

  • 左下角开始

  • 如果当前值 ≤ mid

    • 说明这一列上面的都 ≤ mid
    • 一次性加一整列
  • 如果当前值 > mid

    • 往上移动

这个过程是O(n)的。

Swift 可运行 Demo 代码

classSolution{funckthSmallest(_matrix:[[Int]],_k:Int)->Int{letn=matrix.countvarleft=matrix[0][0]varright=matrix[n-1][n-1]whileleft<right{letmid=left+(right-left)/2letcount=countLessOrEqual(matrix,mid)ifcount<k{left=mid+1}else{right=mid}}returnleft}privatefunccountLessOrEqual(_matrix:[[Int]],_target:Int)->Int{letn=matrix.countvarrow=n-1varcol=0varcount=0whilerow>=0&&col<n{ifmatrix[row][col]<=target{count+=row+1col+=1}else{row-=1}}returncount}}

代码拆解说明

1. 为什么leftright这样初始化
varleft=matrix[0][0]varright=matrix[n-1][n-1]

因为:

  • 矩阵整体是有序的
  • 左上角是最小值
  • 右下角是最大值

这是值域的天然边界

2.count < k为什么要left = mid + 1

这一步非常关键。

含义是:

  • 当前mid太小
  • 小于等于mid的元素还不够k
  • 第 k 小的数一定在右边
3. 为什么最后直接返回left

因为循环结束条件是:

left==right

而这个值,刚好是:

第一个满足“≤ 它的元素个数 ≥ k”的数

也就是第 k 小的元素。

示例测试及结果

letsolution=Solution()print(solution.kthSmallest([[1,5,9],[10,11,13],[12,13,15]],8))// 13print(solution.kthSmallest([[-5]],1))// -5

输出结果:

13 -5

时间复杂度

  • 二分次数:log(maxValue - minValue)
  • 每次统计:O(n)

整体复杂度:

O(n * log(range))

n <= 300的限制下,非常安全。

空间复杂度

除了几个变量,没有额外数据结构:

O(1)

完全满足题目的进阶要求。

总结

LeetCode 378 是一道非常适合用来训练“二分答案思维”的题

  • 不在数组上二分
  • 而是在“可能的结果范围”上二分

这种思路在实际开发中也很常见,比如:

  • 资源分配的最小可行值
  • 系统阈值调优
  • 延迟、吞吐量的临界点搜索

如果你能把这道题讲清楚,
那你对“二分”的理解,已经明显高于只会套模板的人了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 7:04:41

Flink 流处理从入门到精通:DataStream 转换与窗口操作实战

💡 Flink DataStream API 实战全解析:Map、FlatMap、Filter 与 Window 窗口操作详解 封面图建议:深蓝科技感背景,中央 Flink logo,流动线条展示数据流动,关键词“Map / FlatMap / Filter / Window Processing”,简洁直观。 目录 Flink 执行环境与时间语义 基础转换操作…

作者头像 李华
网站建设 2026/4/23 1:07:23

第一次渗透

第一次接触渗透感觉十分的不熟悉&#xff0c;我对前面的课程有很多都没有学到位&#xff0c;很多都听不懂&#xff0c;最初几节课的环境搭建感觉听的云里雾里的。之前授课老师和这门课的老师讲课方式不一样&#xff0c;所以还没有适应。我不知道环境搭建需要那些东西&#xff0…

作者头像 李华
网站建设 2026/4/23 12:30:04

小程序计算机毕设之基于django智能制造业ERP系统定制化ERP系统APP小程序(完整前后端代码+说明文档+LW,调试定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/4/23 12:29:33

《Python动态类型的可靠性屏障:属性测试的实战探索》

Python动态类型机制所带来的编码自由度,是吸引无数开发者深耕于此的核心魅力,却也如同一把双刃剑,在消解静态类型繁琐约束的同时,埋下了类型契约模糊、行为边界失范的隐性隐患,传统测试手段始终被困在“预设输入-验证输出”的点覆盖逻辑里,面对动态类型环境中对象属性动态…

作者头像 李华
网站建设 2026/4/22 19:29:18

无线网络仿真:蓝牙网络仿真_(15).蓝牙网络仿真研究前沿

蓝牙网络仿真研究前沿 1. 蓝牙网络仿真的背景与意义 1.1 无线网络仿真的重要性 无线网络仿真是一种重要的研究工具&#xff0c;用于评估和优化无线通信系统的性能。通过仿真&#xff0c;研究人员可以模拟真实世界中的各种无线通信场景&#xff0c;从而分析网络的行为和性能。无…

作者头像 李华
网站建设 2026/4/23 12:31:45

新手友好 Linux Mint 22.3“Zena“正式发布,带来系统全面升级

如果你想尝试 Linux Mint&#xff0c;现在正是时候。全新改进的"Zena"版本已经到来——仍然基于 Ubuntu Noble&#xff0c;但现在配备了 Cinnamon 6.6、改进的 Wayland 支持&#xff0c;以及更好的国际化功能、新的系统信息和系统管理工具&#xff0c;还有更清晰的图…

作者头像 李华