首页 > 其他分享 >LeetCode题练习与总结:有序矩阵中第 K 小的元素--378

LeetCode题练习与总结:有序矩阵中第 K 小的元素--378

时间:2024-11-06 23:18:00浏览次数:3  
标签:right matrix -- 元素 矩阵 mid 378 LeetCode left

一、题目描述

给你一个 n x n 矩阵 matrix ,其中每行和每列元素均按升序排序,找到矩阵中第 k 小的元素。
请注意,它是 排序后 的第 k 小元素,而不是第 k 个 不同 的元素。

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

示例 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
  • -10^9 <= matrix[i][j] <= 10^9
  • 题目数据 保证 matrix 中的所有行和列都按 非递减顺序 排列
  • 1 <= k <= n^2

二、解题思路

由于矩阵的每一行和每一列都是有序的,我们可以使用二分查找的方法来找到第 k 小的元素。具体步骤如下:

  1. 设置两个指针 left 和 right,分别指向矩阵中的最小值和最大值,即 matrix[0][0] 和 matrix[n-1][n-1]
  2. 计算中间值 mid = (left + right) / 2
  3. 统计矩阵中小于等于 mid 的元素个数 count
  4. 如果 count 小于 k,说明第 k 小的元素在 mid 的右侧,更新 left = mid + 1
  5. 如果 count 大于等于 k,说明第 k 小的元素在 mid 的左侧或等于 mid,更新 right = mid
  6. 重复步骤 2-5,直到 left 等于 right,此时的 left(或 right)即为第 k 小的元素。

三、具体代码

class Solution {
    public int kthSmallest(int[][] matrix, int k) {
        int n = matrix.length;
        int left = matrix[0][0];
        int right = matrix[n - 1][n - 1];
        
        while (left < right) {
            int mid = left + (right - left) / 2;
            int count = 0;
            int j = n - 1;
            
            // 统计小于等于 mid 的元素个数
            for (int i = 0; i < n; i++) {
                while (j >= 0 && matrix[i][j] > mid) {
                    j--;
                }
                count += (j + 1);
            }
            
            if (count < k) {
                left = mid + 1;
            } else {
                right = mid;
            }
        }
        
        return left;
    }
}

四、时间复杂度和空间复杂度

1. 时间复杂度
  • 在 while 循环中,left 和 right 之间的距离在每次迭代后至少减少一半,因为 mid 是通过取 (left + right) / 2 计算得到的。这意味着循环会执行 O(log(max - min)) 次,其中 max 是矩阵中的最大值,min 是矩阵中的最小值。

  • 在每次 while 循环中,我们执行了一个嵌套循环,它遍历矩阵的每一行,并且对于每一行,我们使用一个指针 j 来找到小于等于 mid 的元素个数。这个操作的时间复杂度是 O(n),因为对于每一行,指针 j 最多从列的末尾移动到开头。

由于这两个操作是嵌套的,我们需要将它们的时间复杂度相乘。因此,总的时间复杂度是 O(n * log(max - min))

2. 空间复杂度
  • 我们只使用了常数个额外空间,即 leftrightmidcountj 和循环变量 i。这些变量的大小不随输入矩阵的大小而变化。

  • 我们没有使用任何额外的数据结构,如数组或集合,来存储中间结果。

因此,空间复杂度是 O(1),表示算法使用了固定的额外空间。

五、总结知识点

  • 二分查找算法

    • 使用二分查找来寻找第 k 小的元素,通过不断缩小搜索范围来提高查找效率。
  • 循环和条件判断

    • 使用 while 循环来迭代二分查找过程,直到找到第 k 小的元素。
    • 使用 if-else 语句来判断当前统计的元素个数是否小于 k,从而决定如何调整搜索范围。
  • 矩阵操作

    • 理解矩阵的有序性质,并利用这一性质来优化查找过程。
    • 使用嵌套循环遍历矩阵的行和列。
  • 指针或索引操作

    • 使用变量 j 作为列索引,通过减小 j 的值来找到每行中小于等于 mid 的元素个数。
  • 数学运算

    • 计算中间值 mid 时,使用 (left + right) / 2 防止整数溢出。
    • 使用 count += (j + 1) 来累加每行中小于等于 mid 的元素个数。
  • 边界条件处理

    • 确保在 while 循环中 left 总是小于 right
    • 在计算 mid 时,确保 mid 在 left 和 right 之间。
  • 函数定义和返回值

    • 定义了一个 kthSmallest 方法,接收一个二维整数数组和一个整数 k 作为参数,并返回一个整数结果。

以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。

标签:right,matrix,--,元素,矩阵,mid,378,LeetCode,left
From: https://blog.csdn.net/weixin_62860386/article/details/143533785

相关文章

  • 深入理解 Kafka 的消息持久化机制
    在分布式系统中,消息队列扮演着至关重要的角色。Kafka作为一种高性能、高可靠的分布式消息队列系统,其强大的消息持久化机制是保证数据可靠性的关键。那么,什么是Kafka的消息持久化机制呢?一、Kafka简介Kafka是一个开源的分布式事件流平台,最初由LinkedIn公司开发,后来成为Apac......
  • vuex、vue-router实现原理
    Vuex和VueRouter是Vue.js生态系统中非常重要的两个库,分别用于状态管理和路由管理。它们各自的实现原理如下:Vuex实现原理1.状态管理Vuex是一个专为Vue.js应用程序开发的状态管理模式。它使用集中式的存储管理所有组件的状态,并以一种可预测的方式来确保状态以一种可追......
  • 基于Python的影院电影购票系统
    作者:计算机学姐开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码精品专栏:Java精选实战项目源码、Python精选实战项目源码、大数据精选......
  • shodan的使用方法1(泷羽sec)
    声明学习视频来自B站UP主泷羽sec,如涉及侵泷羽sec权马上删除文章。笔记只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负这节课旨在扩大自己在网络安全方面的知识面,了解网络安全领域的见闻,了解学习哪些知识对于我们渗透......
  • JavasScript 的对象事件的处理程序
    1、鼠标事件常用的鼠标事件有MouseDown、MouseUp、MouseMove、MouseOver、MouseOut、Click、Blur及Focus等事件。mousedown:按下鼠标键时触发 mouseup:抬起鼠标键时触发 click:单击鼠标时触发 dblclick:在同一个元素上双击鼠标时触发 mouseenter:鼠标进入一个节点时触发,进......
  • 常见 HTTP 状态码分类和解释及服务端向前端返回响应时的最完整格式
    目前的开发项目,准备明年的国产化,用了十年的自研系统借这个机会全部重写,订立更严格的规范,这里把返回格式及对应状态码记录一下。常见HTTP状态码及解释HTTP状态码用于表示客户端请求的响应状态,它们分为五类:2xx表示成功,3xx表示重定向,4xx表示客户端错误,5xx表示服务......
  • 【力扣打卡系列】单调栈
    坚持按题型打卡&刷&梳理力扣算法题系列,语言为go,Day20单调栈题目描述解题思路单调栈后进先出记录的数据加在最上面丢掉数据也先从最上面开始单调性记录t[i]之前会先把所有小于等于t[i]的数据丢掉,不可能出现上面大下面小的情况倒着遍历,while遍历,......
  • lanqiaoOJ 1110:小王子单链表 ← 数组模拟实现
     【题目来源】https://www.lanqiao.cn/problems/1110/learning/【题目描述】小王子有一天迷上了排队的游戏,桌子上有标号为1-10的10个玩具,现在小王子将他们排成一列,可小王子还是太小了,他不确定他到底想把哪个玩具摆在哪里,直到最后才能排成一条直线,求玩具的编号。已知他排......
  • 2024年11月 GitHub 十大热门项目排行榜
    欢迎来到2024年11月的GitHub热门项目前十排行榜!无论你是开发者、数据科学家,还是科技爱好者,这些项目在GitHub上都引起了广泛关注。让我们一起看看这些项目独特之处吧!Skyvern-AI/Skyvern......
  • 基于Arduino的数码管显示变阻器模拟量读取值
    题目要求采集变阻器模拟量信号在数码管中显示,要求有二位小数电路连接数码管连接:数码管的七个段(a-g)分别连接到Arduino的引脚2到8。数码管的小数点(dp)连接到Arduino的引脚9。数码管的4个控制引脚连接到Arduino的引脚10到11。变阻器连接:变阻器的模拟输出引脚连接到Arduin......