LeetCode.378. 有序矩阵中第K小的元素
Posted Lucky、Dog
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode.378. 有序矩阵中第K小的元素相关的知识,希望对你有一定的参考价值。
# 该题的标签为 1.堆 2. 二分查找
1. 首先我们用堆的思想来解决该问题
1.1 该矩阵的特点是 n*n 且每行和每列都是有序的
1.2 以上图矩阵为例,我们从行的角度去考虑(也可以从列)
每行的第一个为最小值,我们把1,10,12 放入最小堆
1.3 接下来我们从最小堆中,取出堆顶元素。同时,对于取出的元素,
我们要判断,该元素存不存在下一个元素,如果存在则,把该元素
的下一个元素入堆。
如上图,取出的1,进入的是5. 此时堆内还有 5,10,12
1.4 继续 1.3 当出堆次数为k-1 次时停止。
核心思想就是,每次取出的是当前堆中的最小元素,此时,要
尽快把大于该元素的值放入堆。从行的角度来看,大于该元素的值,
就是行内的下一个元素。
1 class Solution { 2 static class Node implements Comparable<Node> { 3 private int x, y, value; 4 5 public Node(int x, int y, int value) { 6 this.x = x; 7 this.y = y; 8 this.value = value; 9 } 10 11 @Override 12 public int compareTo(Node node) { 13 return this.value - node.value;// 从小到大 14 } 15 16 public int getX() { 17 return x; 18 } 19 20 public int getY() { 21 return y; 22 } 23 24 public int getValue() { 25 return value; 26 } 27 } 28 29 public int kthSmallest(int[][] matrix, int k) { 30 // 使用堆 31 PriorityQueue<Node> pQValues = new PriorityQueue<>(); 32 int n = matrix.length; 33 // 把每一行的第一个元素入堆,每一行的第一个都是该行的最小值 34 for (int x = 0; x < n; x++) { 35 Node _node = new Node(x, 0, matrix[x][0]); 36 pQValues.offer(_node); 37 } 38 // 要找到第k小的数,需要把前k-1个最小的数丢弃掉 39 for (int i = 0; i < k - 1; i++) { 40 Node _node = pQValues.poll();// 从队列中取出一个,一共需要执行k-1次 41 if (_node.getY() == n - 1) { 42 // 如果取到一行中的最后一个 43 continue; 44 } else { 45 // 取该数的下一个 46 Node _n = new Node(_node.getX(), _node.getY() + 1, matrix[_node.getX()][_node.getY() + 1]); 47 pQValues.offer(_n); 48 } 49 } 50 // 此时在最小堆中的第一个元素就是第k个最小值 51 return pQValues.peek().getValue(); 52 } 53 }
2. 使用二分法,后续补充
以上是关于LeetCode.378. 有序矩阵中第K小的元素的主要内容,如果未能解决你的问题,请参考以下文章
leetcode 378 有序矩阵中第k小的元素(二分 or 归并)