22. Median in a Row-wise Sorted Matrix
β GFG solution to find median in a row-wise sorted matrix: efficiently find the median element using binary search on answer technique. π
The problem can be found at the following link: π Question Link
π§© Problem Description
Given a row-wise sorted matrix mat[][]
of size n*m
, where the number of rows and columns is always odd. Your task is to find the median of the matrix.
The median is the middle element when all matrix elements are arranged in sorted order. Since the total number of elements is always odd, there will be exactly one median element.
π Examples
Example 1
Input: mat[][] = [[1, 3, 5],
[2, 6, 9],
[3, 6, 9]]
Output: 5
Explanation: Sorting matrix elements gives us [1, 2, 3, 3, 5, 6, 6, 9, 9].
Hence, 5 is median (middle element at position 4 in 0-indexed array).
Example 2
Input: mat[][] = [[2, 4, 9],
[3, 6, 7],
[4, 7, 10]]
Output: 6
Explanation: Sorting matrix elements gives us [2, 3, 4, 4, 6, 7, 7, 9, 10].
Hence, 6 is median (middle element at position 4 in 0-indexed array).
Example 3
Input: mat = [[3], [4], [8]]
Output: 4
Explanation: Sorting matrix elements gives us [3, 4, 8].
Hence, 4 is median (middle element at position 1 in 0-indexed array).
π Constraints
$1 \le n, m \le 400$
$1 \le \text{mat}[i][j] \le 2000$
Both n and m are always odd
β
My Approach
The optimal approach uses Binary Search on Answer technique combined with upper_bound to efficiently find the median without actually sorting all elements:
Binary Search on Answer + Upper Bound
Initialize Search Range:
Find minimum element:
lo = min(mat[i][0])
for all rows (leftmost elements).Find maximum element:
hi = max(mat[i][m-1])
for all rows (rightmost elements).Calculate required position:
req = (n * m + 1) / 2
(median position).
Binary Search on Possible Values:
For each candidate value
mid
in range[lo, hi]
, count elements β€mid
.Use
upper_bound
on each row to count elements efficiently.
Count Elements β€ Mid:
For each row, use
upper_bound(mat[i].begin(), mat[i].end(), mid)
to find position.Sum up counts from all rows to get total elements β€
mid
.
Adjust Search Range:
If
count < req
: median is larger, solo = mid + 1
.Else: median could be
mid
or smaller, sohi = mid
.
Convergence:
When
lo == hi
, we found the median value.
Key Insight: Since each row is sorted, we can use binary search (upper_bound
) to count elements β€ any value in O(log m) time per row.
π Time and Auxiliary Space Complexity
Expected Time Complexity: O(32 * n * log(m)), where n is the number of rows and m is the number of columns. The factor 32 comes from the maximum number of binary search iterations needed for the range of possible values (since values are bounded by 2000, we need at most logβ(2000) β 11 iterations, but we use 32 as a safe upper bound). For each iteration, we perform upper_bound on n rows, each taking O(log m) time.
Expected Auxiliary Space Complexity: O(1), as we only use a constant amount of additional space for variables like lo, hi, mid, cnt, and req, regardless of the matrix size.
π§βπ» Code (C++)
class Solution {
public:
int median(vector<vector<int>>& mat) {
int n = mat.size(), m = mat[0].size();
int lo = mat[0][0], hi = mat[0][m-1];
for (int i = 1; i < n; i++) {
lo = min(lo, mat[i][0]);
hi = max(hi, mat[i][m-1]);
}
int req = (n * m + 1) >> 1;
while (lo < hi) {
int mid = lo + ((hi - lo) >> 1), cnt = 0;
for (int i = 0; i < n; i++)
cnt += upper_bound(mat[i].begin(), mat[i].end(), mid) - mat[i].begin();
if (cnt < req) lo = mid + 1;
else hi = mid;
}
return lo;
}
};
β Code (Java)
class Solution {
public int median(int[][] mat) {
int n = mat.length, m = mat[0].length;
int lo = mat[0][0], hi = mat[0][m-1];
for (int i = 1; i < n; i++) {
lo = Math.min(lo, mat[i][0]);
hi = Math.max(hi, mat[i][m-1]);
}
int req = (n * m + 1) / 2;
while (lo < hi) {
int mid = lo + (hi - lo) / 2, cnt = 0;
for (int i = 0; i < n; i++) {
int left = 0, right = m;
while (left < right) {
int center = left + (right - left) / 2;
if (mat[i][center] <= mid) left = center + 1;
else right = center;
}
cnt += left;
}
if (cnt < req) lo = mid + 1;
else hi = mid;
}
return lo;
}
}
π Code (Python)
import bisect
class Solution:
def median(self, mat):
n, m = len(mat), len(mat[0])
lo = min(row[0] for row in mat)
hi = max(row[m-1] for row in mat)
req = (n * m + 1) // 2
while lo < hi:
mid = (lo + hi) // 2
cnt = sum(bisect.bisect_right(row, mid) for row in mat)
if cnt < req:
lo = mid + 1
else:
hi = mid
return lo
π§ Contribution and Support
For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: π¬ Any Questions?. Let's make this learning journey more collaborative!
β If you find this helpful, please give this repository a star! β
πVisitor Count
Last updated