leetcode
leetcode 2101 ~ 2150
行排序矩阵的中位数

行排序矩阵的中位数

难度:

标签:

题目描述

代码结果

运行时间: 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作为二分查找的左右边界,这是否意味着矩阵中的元素值必须在这个范围内?
在题解中选择1和10^6作为二分查找的左右边界是基于问题描述中的假设或者对数据范围的一般了解。这种设置不意味着矩阵中元素的值必须严格在这个范围内,但它确实假设了矩阵内的元素值大致在这个范围。若实际应用中矩阵元素的范围已知,应该调整这两个边界以匹配实际情况,从而提高算法的效率和准确性。
🦆
如果矩阵的行并非完全排序,二分查找统计小于等于mid的元素个数的方法是否还适用?
如果矩阵的行并非完全排序,那么使用二分查找结合`bisect_right`来统计小于等于mid的元素个数的方法将不再适用。这是因为`bisect_right`函数假设行是排序的,以便能够快速确定小于等于mid的元素的个数。若行未排序,则必须先对各行进行排序,或者使用其他算法来寻找中位数。
🦆
题解中使用`bisect_right`函数来统计小于等于mid的元素个数,为什么有些情况下我们不使用`bisect_left`?
`bisect_right`函数返回的是插入点的位置,即数组中小于或等于给定值的元素的数量,这正是计算中位数时需要的信息。而`bisect_left`返回的是数组中小于给定值的元素的数量,这在需要统计严格小于某个值的元素数量时使用。在寻找中位数的问题中,我们需要包括等于中间值mid的所有情况,因此使用`bisect_right`更为合适。
🦆
在二分查找的过程中,如何确保最终找到的left值确实是矩阵的中位数,有没有可能存在多个相同的元素值都满足中位数的条件?
在二分查找的过程中,我们通过不断调整left和right的值,缩小查找范围,直至left和right相遇。由于二分查找条件是判断小于等于mid的元素数量是否超过总数的一半,因此最终的left值即为满足条件的最小可能值。实际上,可能存在多个相同的元素值都可以是中位数,尤其是在元素值分布不均或有重复时。算法确保找到的是这些可能值中的最小值,这是符合中位数定义的一种合理解释。

相关问题