Since each row is sorted, we can use binary search on the possible value range to find the median. For each candidate value, count how many elements in the matrix are less than or equal to it using binary search in each row. The median is the value for which this count reaches the middle position.
classSolution {
publicintmatrixMedian(int[][] grid) {
int m = grid.length, n = grid[0].length;
int low = grid[0][0], high = grid[0][n-1];
for (int i = 1; i < m; i++) {
low = Math.min(low, grid[i][0]);
high = Math.max(high, grid[i][n-1]);
}
int k = m * n / 2;
while (low < high) {
int mid = (low + high) / 2, cnt = 0;
for (int[] row : grid) {
int l = 0, r = n;
while (l < r) {
int md = (l + r) / 2;
if (row[md]<= mid) l = md + 1;
else r = md;
}
cnt += l;
}
if (cnt <= k) low = mid + 1;
else high = mid;
}
return low;
}
}
classSolution {
funmatrixMedian(grid: Array<IntArray>): Int {
val m = grid.size
val n = grid[0].size
var low = grid[0][0]
var high = grid[0][n-1]
for (i in1 until m) {
low = minOf(low, grid[i][0])
high = maxOf(high, grid[i][n-1])
}
val k = m * n / 2while (low < high) {
val mid = (low + high) / 2var cnt = 0for (row in grid) {
var l = 0; var r = n
while (l < r) {
val md = (l + r) / 2if (row[md] <= mid) l = md + 1else r = md
}
cnt += l
}
if (cnt <= k) low = mid + 1else high = mid
}
return low
}
}
defmatrix_median(grid: list[list[int]]) -> int:
m, n = len(grid), len(grid[0])
low = min(row[0] for row in grid)
high = max(row[-1] for row in grid)
k = m * n //2while low < high:
mid = (low + high) //2 cnt =0for row in grid:
l, r =0, n
while l < r:
md = (l + r) //2if row[md] <= mid:
l = md +1else:
r = md
cnt += l
if cnt <= k:
low = mid +1else:
high = mid
return low
impl Solution {
pubfnmatrix_median(grid: Vec<Vec<i32>>) -> i32 {
let m = grid.len();
let n = grid[0].len();
letmut low = grid[0][0];
letmut high = grid[0][n-1];
for i in1..m {
low = low.min(grid[i][0]);
high = high.max(grid[i][n-1]);
}
let k = m * n /2;
while low < high {
let mid = (low + high) /2;
letmut cnt =0;
for row in&grid {
letmut l =0;
letmut r = n;
while l < r {
let md = (l + r) /2;
if row[md] <= mid {
l = md +1;
} else {
r = md;
}
}
cnt += l;
}
if cnt <= k {
low = mid +1;
} else {
high = mid;
}
}
low
}
}