leetcode378. Kth Smallest Element in a Sorted Matrix

栏目: 编程工具 · 发布时间: 5年前

内容简介:在一个从左到右,从上到下均有序的二维数组中,找到从小到第k个数字,这里需要注意,不要求一定要是唯一的值,即假设存在这样一个序列当涉及到从一个集合中查找一个元素这样的问题时,我们往往会立刻想到查找的几种方式:有序数组查找,无序数组查找,堆排序。这里如果将二维数组转化为一维有序数组,成本未免太大了。同理,将其中所有元素都转化为堆,也会存在内存不足的问题。因此我们可以采用部分元素堆排序即可。即我们每次只需要可能构成第k个元素的值进行堆排序就可以了。二分查找的核心问题在于,如何找到查找的上界和下届。这边我们可以矩阵

题目要求

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;
    }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

R语言编程艺术

R语言编程艺术

(美)Norman Matloff / 陈堰平、邱怡轩、潘岚锋 等 / 机械工业出版社 / 2013-5 / 69.00

【编辑推荐】 这本书涵盖了R语言编程的诸多方面,尤其在面向对象编程、程序调试、提升程序运行速度以及并行计算等方面,填补了同类图书的空白。关于程序调试的章节更是作者多年经验的总结。不管是初学者还是有一定编程经验的读者,阅读这本书都会有所收获。 ——统计之都 【内容简介】 R语言是世界上最流行的用于数据处理和统计分析的脚本语言。考古学家用它来跟踪古代文明的传播,医药公司用它来探......一起来看看 《R语言编程艺术》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

html转js在线工具
html转js在线工具

html转js在线工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具