【LeetCode: 378. 有序矩阵中第 K 小的元素 + 二分】

|-----------|
| 🚀 算法题 🚀 |

🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀
🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨
🌲 作者简介:硕风和炜,CSDN-Java领域优质创作者🏆,保研|国家奖学金|高中学习JAVA|大学完善JAVA开发技术栈|面试刷题|面经八股文|经验分享|好用的网站工具分享💎💎💎
🌲 恭喜你发现一枚宝藏博主,赶快收入囊中吧🌻
🌲 人生如棋,我愿为卒,行动虽慢,可谁曾见我后退一步?🎯🎯

|-----------|
| 🚀 算法题 🚀 |


🍔 目录

    • [🚩 题目链接](#🚩 题目链接)
    • [⛲ 题目描述](#⛲ 题目描述)
    • [🌟 求解思路&实现代码&运行结果](#🌟 求解思路&实现代码&运行结果)
      • [⚡ 二分](#⚡ 二分)
        • [🥦 求解思路](#🥦 求解思路)
        • [🥦 实现代码](#🥦 实现代码)
        • [🥦 运行结果](#🥦 运行结果)
    • [💬 共勉](#💬 共勉)

🚩 题目链接

⛲ 题目描述

给你一个 n x n 矩阵 matrix ,其中每行和每列元素均按升序排序,找到矩阵中第 k 小的元素。

请注意,它是 排序后 的第 k 小元素,而不是第 k 个 不同 的元素。

你必须找到一个内存复杂度优于 O(n2) 的解决方案。

示例 1:

输入:matrix = [[1,5,9],[10,11,13],[12,13,15]], k = 8

输出:13

解释:矩阵中的元素为 [1,5,9,10,11,12,13,13,15],第 8 小元素是 13

示例 2:

输入:matrix = [[-5]], k = 1

输出:-5

提示:

n == matrix.length

n == matrix[i].length

1 <= n <= 300

-109 <= matrix[i][j] <= 109

题目数据 保证 matrix 中的所有行和列都按 非递减顺序 排列

1 <= k <= n2

进阶:

你能否用一个恒定的内存(即 O(1) 内存复杂度)来解决这个问题?

你能在 O(n) 的时间复杂度下解决这个问题吗?这个方法对于面试来说可能太超前了,但是你会发现阅读这篇文章( this paper )很有趣。

🌟 求解思路&实现代码&运行结果


⚡ 二分

🥦 求解思路
  1. 题目要求在一个 n x n 的有序矩阵中,找到第 k 小的元素。矩阵的每一行和每一列都是非递减排序的。

  2. 二分查找:

    • 使用二分查找的思想,在矩阵的最小值 matrix[0][0] 和最大值 matrix[n-1][n-1] 之间搜索第 k 小的元素。

    • 对于每个中间值 mid,统计矩阵中小于等于 mid 的元素个数 num。

    • 如果 num >= k,说明第 k 小的元素在左半部分,否则在右半部分。

  3. 统计小于等于 mid 的元素个数:

    • 从矩阵的左下角开始,逐行统计小于等于 mid 的元素个数。

    • 如果当前元素 matrix[i][j] <= mid,则该行从 0 到 j 的元素都小于等于 mid,累加 i + 1 到 num,并向右移动 j。

    • 否则,向上移动 i。

  4. 有了基本的思路,接下来我们就来通过代码来实现一下。

🥦 实现代码
java 复制代码
class Solution {
    public int kthSmallest(int[][] matrix, int k) {
        int n = matrix.length;
        int left = matrix[0][0] - 1; // 最小值减 1
        int right = matrix[n - 1][n - 1] + 1; // 最大值加 1
        while (left + 1 < right) {
            int mid = left + ((right - left) >> 1); // 计算中间值
            if (countLessOrEqual(matrix, mid, n) >= k) {
                right = mid; // 第 k 小的元素在左半部分
            } else {
                left = mid; // 第 k 小的元素在右半部分
            }
        }
        return right; // 返回第 k 小的元素
    }

    private int countLessOrEqual(int[][] matrix, int mid, int n) {
        int i = n - 1; // 从左下角开始
        int j = 0;
        int count = 0; // 统计小于等于 mid 的元素个数
        while (i >= 0 && j < n) {
            if (matrix[i][j] <= mid) {
                count += i + 1; // 累加当前列中小于等于 mid 的元素个数
                j++; // 向右移动
            } else {
                i--; // 向上移动
            }
        }
        return count; // 返回统计结果
    }
}
🥦 运行结果

💬 共勉

|----------------------------------|
| 最后,我想和大家分享一句一直激励我的座右铭,希望可以与大家共勉! |

相关推荐
Auc24几秒前
OJ判题系统第6期之判题逻辑开发——设计思路、实现步骤、代码实现(策略模式)
java·开发语言·docker·容器·策略模式
快乐肚皮8 分钟前
深入解析Docker:核心架构与最佳实践
java·运维·docker·容器
zhou18514 分钟前
MySQL保姆级安装教程(附资源包+5分钟极速配置+环境变量调试技巧)
java·python·mysql·php
PgSheep30 分钟前
深入理解 JVM:StackOverFlow、OOM 与 GC overhead limit exceeded 的本质剖析及 Stack 与 Heap 的差异
jvm·面试
GUIQU.1 小时前
【每日一题 | 2025年5.5 ~ 5.11】搜索相关题
算法·每日一题·坚持
不知名小菜鸡.1 小时前
记录算法笔记(2025.5.13)二叉树的最大深度
笔记·算法
小雅痞1 小时前
[Java][Leetcode middle] 55. 跳跃游戏
java·leetcode
com未来1 小时前
使用 NSSM 安装 Tomcat 11.0.6 为 Windows 服务
java·windows·tomcat
TDengine (老段)1 小时前
基于 TSBS 标准数据集下 TimescaleDB、InfluxDB 与 TDengine 性能对比测试报告
java·大数据·开发语言·数据库·时序数据库·tdengine·iotdb
养军博客1 小时前
spring boot3.0自定义校验注解:文章状态校验示例
java·前端·spring boot