行排序矩阵的中位数
难度:
标签:
题目描述
代码结果
运行时间: 49 ms, 内存: 44.9 MB
/**
* LeetCode 2387: Row Sorted Matrix Median
*
* 思路:
* 1. 对于每一行,找到其中位数。
* 2. 将所有行的中位数存储在一个列表中。
* 3. 对于存储了所有行中位数的列表,找到其总体的中位数。
*/
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class SolutionStream {
public int findMedian(int[][] matrix) {
List<Integer> medians = Arrays.stream(matrix)
.map(row -> findRowMedian(row))
.sorted()
.collect(Collectors.toList());
return medians.get(medians.size() / 2);
}
private int findRowMedian(int[] row) {
int n = row.length;
return (n % 2 == 1) ? row[n / 2] : (row[(n / 2) - 1] + row[n / 2]) / 2;
}
public static void main(String[] args) {
SolutionStream solution = new SolutionStream();
int[][] matrix = {{1, 3, 5}, {2, 6, 9}, {3, 6, 9}};
System.out.println(solution.findMedian(matrix)); // 应输出6
}
}
解释
方法:
该题解采用了二分查找的思路来寻找矩阵的中位数。首先,初始化左右指针left和right分别为1和10^6(假设矩阵中的元素值在这个范围内)。然后进行二分查找,每次计算中间值mid,并统计矩阵中小于等于mid的元素个数count。如果count大于等于矩阵元素总数的一半加一(total // 2 + 1),则说明中位数应该在左半部分,更新右指针right为mid;否则,说明中位数在右半部分,更新左指针left为mid + 1。当左右指针相遇时,left即为矩阵的中位数。
时间复杂度:
O(m * log(n) * log(10^6))
空间复杂度:
O(1)
代码细节讲解
🦆
在题解中,为什么选择了1和10^6作为二分查找的左右边界,这是否意味着矩阵中的元素值必须在这个范围内?
▷🦆
如果矩阵的行并非完全排序,二分查找统计小于等于mid的元素个数的方法是否还适用?
▷🦆
题解中使用`bisect_right`函数来统计小于等于mid的元素个数,为什么有些情况下我们不使用`bisect_left`?
▷🦆
在二分查找的过程中,如何确保最终找到的left值确实是矩阵的中位数,有没有可能存在多个相同的元素值都满足中位数的条件?
▷