Median in a Row-Wise Sorted Matrix

medium

You are given a matrix mat of size n x m in which every row is sorted in non-decreasing order. Both n and m are guaranteed to be odd.

Return the median of the matrix — the element that would sit exactly in the middle if all n * m values were lined up in sorted order.

Because n * m is odd, the median is always a single, well-defined element of the matrix; you never average two middle values. Note that only the rows are sorted — there is no ordering guarantee between different rows.

Hints

Sorting all n*m elements works, but the rows are already sorted individually — and the median is just the element of a specific rank. Can you aim for that rank directly?
Pick any value x. How quickly can one sorted row tell you how many of its elements are at most x?
Binary search on the value range: find the smallest x such that at least (n*m)/2 + 1 elements are <= x, counting per row with an upper-bound binary search.

Common doubts

It makes n * m odd, so the sorted order has a single middle element. You never have to average two middle values — the median is always an actual element of mat.
No. It returns the smallest x whose count of elements <= x reaches the median rank. If x were absent from the matrix, x - 1 would have the identical count, contradicting that x was the smallest such value.
No — only each row individually. mat[1][0] can be smaller than mat[0][2]. That is why the value-range bounds scan every row's first and last elements instead of trusting row 0.

Interview follow-ups

Define whether you want the lower median, upper median, or their average. The same rank-counting search works — run it for rank k and rank k + 1 and combine the two results.
Then a staircase walk from a corner counts elements <= x in O(n + m) per probe instead of O(n log m), shaving a log factor off the counting step.
It is the same algorithm with need = k. An alternative is a min-heap over the row heads, popping k times for O(k log n) — better when k is tiny, worse when k is near n*m/2.

Fun facts

  • The binary search here never touches the matrix's order directly — it searches the value space 1..2000, which takes at most about 11 probes no matter how big the matrix gets.
  • The guess-and-count pattern — binary search on the answer — reappears in K-th Smallest Element in a Sorted Matrix, Allocate Books, and Split Array Largest Sum: whenever checking a candidate is easy but constructing the answer is hard.

Asked at

AmazonMicrosoftAdobeSamsung
Frequently Sometimes Occasionally
Example 1
Input: n = 3, m = 3, mat = [[1, 3, 5], [2, 6, 9], [3, 6, 9]]
Output: 5
All elements in sorted order: [1, 2, 3, 3, 5, 6, 6, 9, 9]. The middle (5th of 9) element is 5.
Example 2
Input: n = 3, m = 3, mat = [[2, 4, 9], [3, 6, 7], [4, 7, 10]]
Output: 6
All elements in sorted order: [2, 3, 4, 4, 6, 7, 7, 9, 10]. The middle element is 6.
Example 3
Input: n = 3, m = 1, mat = [[3], [4], [8]]
Output: 4
All elements in sorted order: [3, 4, 8]. The middle element is 4.
Constraints

- 1 <= n, m <= 400 - n and m are both odd - 1 <= mat[i][j] <= 2000

Solve this problem →