首页 > 编程语言 >力扣378(java&python)-有序矩阵中第 K 小的元素(中等)

力扣378(java&python)-有序矩阵中第 K 小的元素(中等)

时间:2022-12-06 14:56:02浏览次数:47  
标签:right java matrix python 元素 mid 力扣 int left

题目:

给你一个 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 )很有趣。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/kth-smallest-element-in-a-sorted-matrix
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

【二分查找】

根据题意得知二维矩阵从左向右依次递增,从上到小依次递增,故可得知, matrix[0][0]是最小值, matrix[n-1][n-1]是最大值。所需找的第k小的元素一定在最大值与最小值这个区间中, 现在将题目意思转换为在一个有序范围中查找值,可以考虑使用二分查找。

让 left =  matrix[0][0],right =  matrix[n-1][n-1],计算出mid的值,这样矩阵就会以mid为界限,分为两个部分。一部分元素是小于等于mid的部分,一部分是大于mid的部分。然后就需要判断第k小的元素到底在哪一个部分?(这样就可以明白,在较小的部分中至少应该有k个元素)

找比mid小的元素怎么找:

  • 初始位置在 matrix[n - 1][0](即左下角);
  • 设当前位置为 matrix[i][j],若 matrix[i][j] ≤ mid,则此元素及上方所有元素都是比mid 小的数,计算出这一列比mid小的元素累加到count中,并继续向右移动,否则,matrix[i][j] > mid,就需要向上移动才可能能找到比mid小的元素了;
  • 不断移动直到走出格子为止。

比较count 与 k(二分查找):

  • 循环条件:left < right, mid = left + (right - left) / 2;
  • 如果count >= k,说明小元素部分的范围太大了(count==k时,表示刚好),则需要缩小 小元素的范围,即right = mid;
  • 如果count < k,说明小元素部分的范围太小了,则需要扩大 小元素的范围,即left = mid + 1;
  • 循环结束时:left == right,left或者right即为答案。

java代码:

 1 class 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 < right){
 6             int mid = left + (right - left) / 2;
 7             if (check(matrix, mid, k)){
 8                 //true:count < k
 9                 left = mid + 1;
10             }else{
11                 //flase:count >= k
12                 right = mid;
13             }
14         }
15         return left;
16     }
17     public boolean check(int[][] matrix, int mid, int k){
18         int n = matrix.length;
19         int i = n-1, j = 0;
20         int count = 0;
21         while (i >= 0 && j < n){
22             if (matrix[i][j] <= mid){
23                 //当前元素小于等于mid,则当前元素及改列上方的元素都小于mid
24                 count += i + 1;
25                 //继续向右移动
26                 j += 1;
27             }else{
28                 //否则,向上查找小于mid的元素
29                 i -= 1;
30             }
31         }
32         return count < k;
33     }
34 }

 python3代码:

 1 class Solution:
 2     def kthSmallest(self, matrix: List[List[int]], k: int) -> int:
 3         n = len(matrix)
 4         def check(mid):
 5             i, j, count = n-1, 0, 0
 6             while i >= 0 and j < n:
 7                 if matrix[i][j] <= mid:
 8                     count += i + 1
 9                     j += 1
10                 else:
11                     i -= 1
12             return count < k
13         left, right = matrix[0][0], matrix[n-1][n-1]
14         while left < right:
15             mid = left + (right - left) // 2
16             if check(mid):
17                 left = mid + 1
18             else:
19                 right = mid
20         return left

标签:right,java,matrix,python,元素,mid,力扣,int,left
From: https://www.cnblogs.com/liu-myu/p/16954671.html

相关文章

  • JAVA8 steam 常用示例
    packagehk.org.ha.tims;importhk.org.ha.tims.dto.vo.UserRoleVo;importlombok.Data;importjava.util.*;importjava.util.function.Function;importjava.util.stream......
  • python 处理docker inspect json 数据
    #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#pipinstallpandas#pipinstallopenpyxl####http://192.168.145.37:8090/nationExchang......
  • bug处理记录:Java HotSpot(TM) 64-Bit Server VM warning: ignoring option PermSize=5
    1.报错:JavaHotSpot(TM)64-BitServerVMwarning:ignoringoptionPermSize=512M;supportwasremovedin8.02.导致原因:错误场景:当前使用的办公电脑的内存配置为......
  • Java中的反射机制及反射的优缺点
    1.反射的概念反射机制指的是,程序在运行时能够获取自身的信息。在java中只要给定类的名字,就能够获取类的所有属性和方法。反射是Java中很多高级特性的基础,比如注......
  • java (String)强制转换与toString()方法
    1.Object.toString()介绍Object中是自带有toString()方法的,也就是说java中的所有类的对象都是可以转换为字符串的。首先,先看看Object.toString()的默认实现public......
  • 有关JavaSe基础的反射知识总结
    反射这门技术在说之前首先来介绍一下动态语言和静态语言动态语言:在服务器运行的期间可以改变其结构的语言,在运行时代码可以根据某些条件来改变自身的结构,我们目前学习到的......
  • Python监测文件
    #-*-coding:utf-8-*-#use:pythonfile_check.py./#放在/var/www/或/var/www/html下执行这个脚本,它会先备份当然目录下的所有文件,然后监控当前目录,#一旦当前目......
  • 【python】字符串、转义字符、字符串常用方法
    1.字符串字符串用单引号或双引号包围起来,三个双引号或三个单引号开头的字符串可以换行。s1='hello,world's2="hello,world"s3='''hello,money,rice'''s3=......
  • java方法的总结
    1.方法的作用:封装一段代码结构,可以被重复调用以提高的复用性,提高开发效率,让程序逻辑更清晰2.方法的完整的格式 修饰词返回值方法名(形参列表,形参列表){ . .. ......
  • Java中的Scanner用法解析
    (10条消息)Java中的Scanner用法解析_普通网友的博客-CSDN博客_javascannerjava-Picocli-快速构建Java命令行程序_个人文章-SegmentFault思否......