Kth Smallest Element in a Sorted Matrix
Treat each row as a sorted list. Keep a min-heap with one cell per row: the first cell of that row you have not used yet. The smallest cell in the heap is the next smallest value in the matrix. Take it out, then push the cell to its right in the same row. The next smallest value is always the front of some row.
The smallest unused value in the whole matrix is always the smallest front in the heap, because each row's unused cells are sorted and its front is the smallest of them.
Problem
You get an n × n matrix. Every row is sorted from smallest to largest, and every column is sorted from top to bottom. Values can repeat.
Return the k-th smallest value in the whole matrix. Repeats count as separate places: if the value 13 appears twice, the two copies take two places in the order.
An n × n integer matrix matrix with sorted rows and columns, and an integer k.
One integer: the k-th smallest value among all n² cells.
Read all nine values in order: 1, 5, 9, 10, 11, 12, 13, 13, 15. The 8th one is 13.
There is only one cell, so it is the 1st smallest.
- • n == matrix.length == matrix[i].length
- • 1 ≤ n ≤ 300
- • −10^9 ≤ matrix[i][j] ≤ 10^9
- • All the rows and columns of matrix are guaranteed to be sorted in non-decreasing order
- • 1 ≤ k ≤ n^2
- • Follow-up: Could you solve the problem with a constant memory (i.e., O(1) memory complexity)?
- • Follow-up: Could you solve the problem in O(n) time complexity? (very advanced; not expected in interviews)
First, think yourself
Before opening any solution, try to answer these on paper. Use hints only when stuck — each hint is counted.
- 1.
Each row is sorted. Where could the smallest value in the whole matrix be?
- 2.
If I read the matrix row after row, is that one sorted list? Check it with the 9 and the 10 in the first example.
- 3.
Do I need every value in sorted order, or only the k-th one?
- 4.
After I use one cell from a row, which cell in that row could be the next candidate?
- 5.
When k is small, do I need to look at all n rows to find the answer?
Brute force approach
Better approach
Optimized approach
Why does this algorithm work?
Dry run
All approaches compared
| Approach | Idea | Time | Space |
|---|---|---|---|
| Brute Force | Copy all n² values into one list, sort it, and read position k | O(N² log N) | O(N²) |
| Better | Scan every cell and keep a max-heap of the k smallest seen; its top is the answer | O(N² log K) | O(K) |
| Optimal | Min-heap with one front cell per row; take k values out and push the cell to the right | O(K log min(N, K)) | O(min(N, K)) |
Why does this belong to this pattern?
- “each row is sorted”Every row is already a sorted list. We can merge the rows instead of sorting them all again.
- “k-th smallest”Only the first k values taken out in order matter. Stop after k pops.
- “rows and columns both sorted”Column 0 is sorted too, so the first cells of the rows let us decide how many rows to start.
This is the anchor of the Kth-across sub-pattern. The rows are sorted lists, so the next smallest value is always the front of some row, and a heap finds it. Unlike Top K, the heap is not a filter on all values: it holds one cell per row, and the pops themselves put the values in order. The next question keeps the same heap but the lists are the pairs of two arrays.
Don't make this mistake
Rows are sorted, but row 1 does not continue where row 0 stops. On [[1,5,9],[10,11,13],[12,13,15]] with k = 6, the formula reads matrix[1][2] = 13. The correct answer is 12, which sits in row 2. Row 2's first cell is smaller than the end of row 1, so a row-by-row count skips it.
A default priority_queue pops the largest value first. Seeded with the fronts 1, 10 and 12, the first pop is 12 (row 2), not 1, so the values come out from the largest end and the answer is wrong.
When a row's last cell is taken out, c + 1 = n is past the end of the row. The read is out of bounds, and the heap gets a garbage value.
Want to implement this?
Write it yourself on LeetCode, then come back and compare your code with the solutions above.
Open coding workspaceHow this concept connects to System Design & C++ Systems
Top engineering interviews test whether you understand how algorithms like K-way Merge translate into production architectures and low-level memory mechanics.
Foundations: Object-Oriented Principles in C++23
Class invariants, pure virtual interfaces, and RAII smart pointers.
Food Delivery System (Zomato Architecture)
Real-world machine coding application of algorithms and design patterns.
Pointers vs References Deep Dive
Pointer arithmetic and memory layout under the hood.
Virtual Method Table (vtable) & Memory Layout
Polymorphism, vptr overhead, and multiple inheritance in memory.