leetcode官网_leetcode有多少题

leetcode官网_leetcode有多少题leetcode378. Kth Smallest Element in a Sorted Matrix

大家好,又见面了,我是你们的朋友全栈君。

题目要求

Given a n x n matrix where each of the rows and columns are sorted in ascending order, find the kth smallest element in the matrix.

Note that it is the kth smallest element in the sorted order, not the kth distinct element.

Example:

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

return 13.
Note: 
You may assume k is always valid, 1 ≤ k ≤ n2.

在一个从左到右,从上到下均有序的二维数组中,找到从小到第k个数字,这里需要注意,不要求一定要是唯一的值,即假设存在这样一个序列1,2,2,3,则第三个数字是2而不是3。

思路一:优先队列

当涉及到从一个集合中查找一个元素这样的问题时,我们往往会立刻想到查找的几种方式:有序数组查找,无序数组查找,堆排序。这里如果将二维数组转化为一维有序数组,成本未免太大了。同理,将其中所有元素都转化为堆,也会存在内存不足的问题。因此我们可以采用部分元素堆排序即可。即我们每次只需要可能构成第k个元素的值进行堆排序就可以了。

    public int kthSmallest(int[][] matrix, int k) {
        //优先队列
        PriorityQueue<Tuple> queue = new PriorityQueue<Tuple>();
        //将每一行的第一个元素放入优先队列中
        for(int i = 0 ; i<matrix.length ; i++) {
            queue.offer(new Tuple(i, 0, matrix[i][0]));
        }
        
        //对优先队列执行k次取操作,取出来的就是第k个值
        for(int i = 0 ; i<k-1 ; i++) {
            Tuple t = queue.poll();
            //判断是否到达行尾,若没有,则将下一个元素作为潜在的第k个元素加入优先队列中
            if(t.y == matrix[0].length-1) continue;
            queue.offer(new Tuple(t.x, t.y+1, matrix[t.x][t.y+1]));
        }
        return queue.poll().value;
    }
    
    /**
    * 存储矩阵中x,y和该下标上对应的值的Tuple
    */
    public static class Tuple implements Comparable<Tuple>{
        int x;
        int y;
        int value;
        
        public Tuple(int x, int y, int value) {
            this.x = x;
            this.y = y;
            this.value = value;
        }
        @Override
        public int compareTo(Tuple o) {
            // TODO Auto-generated method stub
            return this.value - o.value;
        }
    }

思路二:二分法查找

二分查找的核心问题在于,如何找到查找的上界和下届。这边我们可以矩阵中的最大值和最小值作为上界和下界。然后不停的与中间值进行比较,判断当前矩阵中小于该中间值的元素有几个,如果数量不足k,就将左指针右移,否则,就将右指针左移。直到左右指针相遇。这里需要注意,不能在数量等于k的时候就返回mid值,因为mid值不一定在矩阵中存在。

    public int kthSmallest2(int[][] matrix, int k){
        int low = matrix[0][0], high = matrix[matrix.length-1][matrix[0].length-1];
        while(low <= high) {
            int mid = low + (high - low) / 2;
            int count = 0;
            int i = matrix.length-1 , j = 0;
            //自矩阵左下角开始计算比mid小的数字的个数
            while(i>=0 && j < matrix.length){
                if(matrix[i][j]>mid) i--;
                else{
                    count+=i+1;
                    j++;
                }
            }
            if(count < k) {
                low = mid + 1;
            }else{
                high = mid - 1;
            }
        }
        return low;
    }
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/107013.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Django(76)isort工具对import导入进行排序

    Django(76)isort工具对import导入进行排序前言我们在开发项目时经常会进行导包有import*格式的,还有from*import*格式的,最后就会显示的很乱,那么有没有什么工具能对导包进行一键排序呢?答案是有的,使用isort工具i

    2022年7月30日
    9
  • 常见的数据交换方式有电路交换,报文交换_电路交换网络有哪些

    常见的数据交换方式有电路交换,报文交换_电路交换网络有哪些Q:如何实现数据通过网络核心从源主机到达目的主机(互联的路由器网络)A:采用的方法:数据交换网络结构包括网络边缘、接入网络和网络核心网络核心主要解决的问题就是将源主机发送数据送达目的主机对于一

    2022年8月1日
    2
  • 您不具有该 Vuser 类型的许可证. 请与 HP Software 联系以更新许可证.

    您不具有该 Vuser 类型的许可证. 请与 HP Software 联系以更新许可证.

    2021年7月17日
    62
  • java中数组初始化方法_java数组初始化赋值

    java中数组初始化方法_java数组初始化赋值java中初始化数组的方式有几种发布时间:2020-06-0116:12:45来源:亿速云阅读:153作者:鸽子三种初始化方式:1、静态初始化:创建+赋值2、动态初始化:先创建再赋值3、默认初始化:创建之后若不赋值则会被赋对应数据类型的默认值我们来看一下具体代码:publicclassTest3{publicstaticvoidmain(String[]args){//1、声明…

    2022年10月19日
    2
  • python3获取Elasticsearch数据库数据

    python3获取Elasticsearch数据库数据python3获取Elasticsearch数据库数据采用scoll滚动搜索,scoll搜索会在第一次搜索的时候保存一个当时的视图快照,之后只会基于该旧的视图快照提供数据搜索,这个期间数据变更,用户是看不到的,每次发送scoll请求,需要指定一个scoll参数,指定一个时间窗口,每次搜索请求只要在这个时间窗口内完成就可以了。1.python利用scroll_id游标遍历查询es,获取错误日志路…

    2022年5月10日
    69
  • 表结法和账结法_我国采用表结法还是账结法

    表结法和账结法_我国采用表结法还是账结法为了计算出当期利润,通常采用两种方法:表结法和账结法。国内一些财务系统多采用账结法,这似乎比较符合中国式习惯。即:期末,损益类的虚账户的余额结转汇总到本年利润科目,最后账户无余额;资产负债类实账户结

    2022年8月4日
    6

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号