p147 行列递增矩阵中第 K 小的元素(leetcode 378)
一:解题思路
之前做过一些求第K小或者第K大的元素的题目。一旦题目需要你求第K小或者第K大的元素的时候,这个时候就需要想到堆这个数据结构。
方法一:使用一个最大堆来做。当堆中的元素不足K个的时候,我们就不断的将矩阵中的元素加入堆中。然后接着遍历矩阵后面的其他元素,当遍历的元素小于堆顶元素的时候,加入堆中。如果大于堆顶元素这不用加入堆中。这种方法并没有用到行列递增的这个特性,所以会有更优的解法。Time:O(m*n*log(k)),Space:O(k)
方法二:加入了题目中所给的行列递增的特性。 Time: O(k*log(k)), Space: O(k)
二:完整代码示例 (C++版和Java版)
方法一C++:
class Solution { private: priority_queue<int, vector<int>, less<int>> maxHeap; public: int kthSmallest(vector<vector<int>>& matrix, int k) { int m = matrix.size(); int n = matrix[0].size(); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (maxHeap.size() < k) { maxHeap.push(matrix[i][j]); } else if (matrix[i][j] < maxHeap.top()) { maxHeap.pop(); maxHeap.push(matrix[i][j]); } } } return maxHeap.top(); } };
方法一Java:
class Solution { private Queue<Integer> maxHeap=new PriorityQueue<>(Collections.reverseOrder()); public int kthSmallest(int[][] matrix, int k) { int m=matrix.length; int n=matrix[0].length; for(int i=0;i<m;i++) { for(int j=0;j<n;j++) { if(maxHeap.size()<k) { maxHeap.add(matrix[i][j]); } else if(matrix[i][j]<maxHeap.peek()) { maxHeap.poll(); maxHeap.add(matrix[i][j]); } } } return maxHeap.peek(); } }
方法二C++:
方法二Java:
class Solution { class Elem implements Comparable<Elem> { int row; int col; int val; Elem(int row,int col,int val) { this.row=row; this.col=col; this.val=val; } @Override public int compareTo(Elem o) { return this.val-o.val; } } public int kthSmallest(int[][] matrix, int k) { int m=matrix.length; int n=matrix[0].length; Queue<Elem> minHeap=new PriorityQueue<>(); for(int i=0;i<m && i<k;i++) minHeap.add(new Elem(i,0,matrix[i][0])); for(int i=0;i<k-1;i++) { Elem e=minHeap.poll(); e.col++; if(e.col<n) { e.val=matrix[e.row][e.col]; minHeap.add(e); } } return minHeap.peek().val; } }

浙公网安备 33010602011771号