K-th smallest number in sorted matrix

LeetCode problem 378. Kth Smallest Element in a Sorted Matrix.

## Problem description

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.
## Analysis

One trick we can use is **Manhattan distance**.

Manhattan distance
Since we know that the top-left element (A[0][0]) is the 1st smallest element, then we know that *k*-th smallest element must have Manhattan distance ≤ *k*-1 from the top-left element.

Illustration
***k* = 4**, i.e. find the **4th smallest** element.

* Lightgray color: top-left element.
* Yellow color: elements that have Manhattan distance ≤ 4 - 1 = 3 from the top-left element.
* Lime color: correct result.

Based on the illustration above, we only need to push in the elements in the top-left triangle into a min-heap.

Then we pop from the min-heap *k* times to get the desired result.

### Complexity analysis

#### Time complexity

1. The top-left triangle that we use to build the heap has

k
2

/

2

{\displaystyle k^2 / 2}

 elements. So the time complexity of extracting these elements is O(*k*2).
2. Building the min-heap has time complexity O(*k*2 log *k*2).
3. Popping off from the min-heap has time complexity O(*k* log *k*2).

So total time complexity is **O(*k*2 log *k*2)**.

#### Space complexity

Stack
Since we do not have recursion here, the stack space complexity is O(1).
Heap
Our auxiliary object is the min-heap, which has at most

k
2

/

2

{\displaystyle k^2 / 2}

 elements. So the heap space complexity is O(*k*2).
So the total space complexity is **O(*k*2)**.

## Solution

### C++

```
class Solution {
public:
 int kthSmallest(const std::vector<std::vector<int>>& matrix, const int& k) {
 int rows = matrix.size(), cols = matrix[0].size();

 // feed the top left isosceles right triangle into the min-heap
 // trick: Manhattan Distance
 std::priority\_queue<int, std::vector<int>, std::greater\_equal<int>> minHeap;
 for (int row = 0; row < std::min(k, rows); ++row) {
 for (int col = 0; col < std::min(k - row, cols); ++col) {
 minHeap.push(matrix[row][col]);
 }
 }

 // get result by popping from the min-heap
 int i = 0, result = 0;
 while ((!minHeap.empty()) && (i < k)) {
 result = minHeap.top();
 minHeap.pop();
 ++i;
 }
 return result;
 }
};

```

### Java

```
class Solution {
 public int kthSmallest(int[][] matrix, int k) {
 int rows = matrix.length, cols = matrix[0].length;

 // feed the top left isosceles right triangle into the min-heap
 // trick: Manhattan Distance
 PriorityQueue<Integer> minHeap = new PriorityQueue<>();
 for (int row = 0; row < Math.min(k, rows); ++row) {
 for (int col = 0; col < Math.min(k - row, cols); ++col) {
 minHeap.offer(matrix[row][col]);
 }
 }

 // get result by popping from the min-heap
 int i = 0, result = 0;
 while ((!minHeap.isEmpty()) && (i < k)) {
 result = minHeap.poll();
 ++i;
 }
 return result;
 }
}

```

## Notes

### C++

* `std::priority_queue`
	+ To construct a min-heap, the comparison type is `std::greater_equal`.
	+ The full declaration of a min-heap would be
	```
	std::priority\_queue<int, std::vector<int>, std::greater\_equal<int>> minHeap;

	```