每天一道leetcode378-有序矩阵中第K小的元素

前言

大家看每天一道leetcode的,帮忙投个票~

今天发起了leetcode刷题投票&粉丝福利活动,见我公众号今天的另一篇。11.1号打卡~

题目

leetcode378-有序矩阵中第K小的元素

英文链接:

https://leetcode.com/problems/kth-smallest-element-in-a-sorted-matrix/

中文链接:

https://leetcode-cn.com/problems/kth-smallest-element-in-a-sorted-matrix/

分类:二分查找类

题目详述

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

示例:

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

返回 13。

说明: 
你可以假设 k 的值永远是有效的, 1 ≤ k ≤ n2 。

暴力解决

思路

  1. 额,看到这个题目,一开始大体思路就是暴力解决;

  2. 遍历整个二维数组,然后把这个二维数组存到一个一维数组中,然后对这个一维数组,进行排序,然后取这个一维数组第k个值就行。

代码

 1class Solution {
2    public int kthSmallest(int[][] matrix, int k) {
3        if(matrix.length == 0 || matrix[0].length == 0)
4            return -1;
5        int rows = matrix.length;
6        int cols = matrix[0].length;
7        int number = rows * cols;
8        int [] list = new int[number];
9        int count = 0;
10        for(int i=0;i<rows;i++)
11        {
12            for(int j=0;j<cols;j++)
13            {
14                list[count] = matrix[i][j];
15                count++;
16            }
17        }
18        Arrays.sort(list);
19        return list[k-1];
20    }
21}

二分解决

思路

  1. 由于是一个矩阵,左上角的数是最小值,右下角的数是最大值,所以可以利用这一个特点来进行二分,每次取两个边界的值进行除以2,得到一个mid值;

  2. 然后根据这个mid值,统计整个矩阵中,小于mid值的个数,如果小于mid的值的个数刚好大于等于k个,那么说明应该缩小right的值到mid,如果小于k个,那么说明left应该变成mid;

  3. 这样一步步进行紧逼,找到最后的这个数据。

代码

 1class Solution {
2    public int kthSmallest(int[][] matrix, int k) {
3        int n = matrix.length;
4        int left = matrix[0][0], right = matrix[n - 1][n - 1];
5        while (left + 1 < right) {
6            int mid = (right - left) / 2 + left;
7            int num = count(matrix, mid);
8            if (num >= k) {
9                right = mid;
10            } else {
11                left = mid;
12            }
13        }
14        if (count(matrix, right) <= k - 1return right;
15        return left;
16    }
17    public int count(int[][] matrix, int target) {
18        int n = matrix.length;
19        int i = n - 1, j = 0;
20        int res = 0;
21        while (i >= 0 && j < n) {
22            if (matrix[i][j] < target) {
23                res += i + 1//index + 1 = number of elements.
24                j++;
25            } else {
26                i--;
27            }
28        }
29        return res;
30    }
31}

代码讲解

  1. 17行到30行代码就是求矩阵中小于target的数的大小,这里的话从第0列开始的最底层开始找,如果左下角的数比target小,那么说明这一列的数都是小于target所以,也就是出现了代码22行到24行,因为这个一列已经找过了,所以j++,移动到下一列去找;

  2. 如果左下角的数比target大,由于每一行递增,所以只能是i--,来去找下一行;以上就是对17行-30行代码的讲解

  3. 题目中使用了二分查找,去找最小值和最大值的中间值,如果小于中间值的个数是k个或者大于k个,那么让right去等于mid,往左边逼近;

  4. 如果小于中间值mid的个数是小于k的,那么说明不够k个,也就只能取把left变大,等于mid;

  5. 然后循环结束的条件是left+1<right;说明这时候结束的时候已经是left与right无限逼近了,这个时候left与right的中间值在数组里面(这里我也没有数学证明,left与right一直求中间值,那么最后中间值mid一定在数组里面???这个我自己试验了几个数组,确实是这样子,但是我数学能力有限,无法去证明,有人能证明吗,欢迎评论区留言

结束语

2018.11.1打卡~

END

推荐阅读

leetcode34-在排序数组中查找元素的第一个和最后一个位置

每天一道leetcode240-在二维数组中搜索n升级版

扫一扫

640?wx_fmt=jpeg

有3T编程资料等你来拿



同步定位与地图构建(SLAM)技术为移动机器人或自主载具在未知空间中的导航提供了核心支撑。借助该技术,机器人能够在探索过程中实时构建环境地图并确定自身位置。典型的SLAM流程涵盖传感器数据采集、数据处理、状态估计及地图生成等环节,其核心挑战在于有效处理定位与环境建模中的各类不确定性。 Matlab作为工程计算与数据可视化领域广泛应用的数学软件,具备丰富的内置函数与专用工具箱,尤其适用于算法开发与仿真验证。在SLAM研究方面,Matlab可用于模拟传感器输出、实现定位建图算法,并进行系统性能评估。其仿真环境能显著降低实验成本,加速算法开发与验证周期。 本次“SLAM-基于Matlab的同步定位与建图仿真实践项目”通过Matlab平台完整再现了SLAM的关键流程,包括数据采集、滤波估计、特征提取、数据关联与地图更新等核心模块。该项目不仅呈现了SLAM技术的实际应用场景,更为机器人导航与自主移动领域的研究人员提供了系统的实践参考。 项目涉及的核心技术要点主要包括:传感器模型(如激光雷达与视觉传感器)的建立与应用、特征匹配与数据关联方法、滤波器设计(如扩展卡尔曼滤波与粒子滤波)、图优化框架(如GTSAM与Ceres Solver)以及路径规划与避障策略。通过项目实践,参与者可深入掌握SLAM算法的实现原理,并提升相关算法的设计与调试能力。 该项目同时注重理论向工程实践的转化,为机器人技术领域的学习者提供了宝贵的实操经验。Matlab仿真环境将复杂的技术问题可视化与可操作化,显著降低了学习门槛,提升了学习效率与质量。 实践过程中,学习者将直面SLAM技术在实际应用中遇到的典型问题,包括传感器误差补偿、动态环境下的建图定位挑战以及计算资源优化等。这些问题的解决对推动SLAM技术的产业化应用具有重要价值。 SLAM技术在工业自动化、服务机器人、自动驾驶及无人机等领域的应用前景广阔。掌握该项技术不仅有助于提升个人专业能力,也为相关行业的技术发展提供了重要支撑。随着技术进步与应用场景的持续拓展,SLAM技术的重要性将日益凸显。 本实践项目作为综合性学习资源,为机器人技术领域的专业人员提供了深入研习SLAM技术的实践平台。通过Matlab这一高效工具,参与者能够直观理解SLAM的实现过程,掌握关键算法,并将理论知识系统应用于实际工程问题的解决之中。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值