378. Kth Smallest Element in a Sorted Matrix

Problem:
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.
6/13/2018 update:
Another and more efficient approach is using binary search. Very similar to quick select. If number of numbers less than and equal to mid is greater than k, we know that result is on left.


class Solution {
    public int kthSmallest(int[][] matrix, int k) {
        int m = matrix.length, n = matrix[0].length;
        int lo = matrix[0][0], hi = matrix[m - 1][n - 1] + 1;
        while (lo < hi) {
            int mid = lo + (hi - lo) / 2;
            int count = 0, j = n - 1;
            for (int i = 0; i < m; i++) {
                while (j >= 0 && matrix[i][j] > mid) j--;
                count += (j + 1);
            }
            if (count < k) lo = mid + 1;
            else hi = mid;
        }
        return lo;
    }
}

--------------------------------------------------------------------------------------------------------------------------

Analysis:
N sorted array problem should use heap.

  1. offer first row in heap
  2. pop from heap, offer cell below popped to heap. 
  3. pop k - 1 times, the heap top is kth smallest element. 
Benefit of the above approach is that it avoids visited matrix.

Solution:

class Solution {
    class Tuple {
        int x; 
        int y;
        int val;
        public Tuple (int x, int y, int val) {
            this.x = x;
            this.y = y;
            this.val = val;
        }
    }
    public int kthSmallest(int[][] matrix, int k) {
        int counter = 0, res = 0, m = matrix.length, n = matrix[0].length;
        PriorityQueue<Tuple> queue = new PriorityQueue<>(k, new Comparator<Tuple>(){
            public int compare(Tuple a, Tuple b) {
                return a.val - b.val;
            }
        });
        for (int i = 0; i < n; i++) {
            queue.offer(new Tuple(0, i, matrix[0][i]));
        }
        for (int i = 0; i < k -1; i++) {
            Tuple cur = queue.poll();
            if (cur.x == n - 1) continue;
            queue.offer(new Tuple(cur.x + 1, cur.y, matrix[cur.x + 1][cur.y]));
        }
        return queue.peek().val;

    }
}

评论

此博客中的热门博文

663. Equal Tree Partition

776. Split BST

426. Convert Binary Search Tree to Sored Doubly Linked List