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. 使用二分法,后续补充

猜你喜欢

转载自www.cnblogs.com/infoo/p/11922511.html