寻找两个有序数组的中位数

给定两个大小分别为 mn 的正序(从小到大)数组 nums1nums2。请你找出并返回这两个正序数组的 中位数

算法的时间复杂度应该为 O(log (m+n))

示例 1:

复制代码
输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
解释:合并数组 = [1,2,3] ,中位数 2

示例 2:

复制代码
输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5

在编程中,我们常遇到需要找两个已排序数组的中位数的问题。这个问题看似简单,但当数组非常大时,直接合并数组再计算中位数的时间复杂度可能会很高。今天,我们将介绍一个高效的算法,利用二分查找技术来降低时间复杂度。

问题背景

给定两个已排序的数组 nums1nums2,我们的目标是找出这两个数组合并后的中位数。可以通过以下几种方法来解决,但最有效的方法是使用二分查找。

算法思想
  1. 保证较短的数组参与二分查找

    首先,我们保证对较短的数组进行二分查找,这样可以减少查找的范围。我们交换 nums1nums2,确保 nums1 总是较短的那个数组。

  2. 虚拟边界的引入

    为了方便判断边界条件,我们在两个数组的两端引入虚拟值:Integer.MIN_VALUEInteger.MAX_VALUE。这些虚拟值的引入简化了对数组两端的边界检查,避免了处理边界时的复杂逻辑。

  3. 二分查找

    通过对较短的数组 nums1 进行二分查找,寻找合适的切分点。每次切分后,检查切分是否满足中位数的条件:左边部分的最大值不大于右边部分的最小值。

  4. 计算中位数

    一旦找到了合适的切分点,就可以根据数组的总长度来计算中位数。如果总长度是奇数,返回左边部分的最大值;如果是偶数,返回左边最大值和右边最小值的平均值。

算法实现
java 复制代码
class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        if (nums1.length > nums2.length) {
            int[] tmp = nums1;
            nums1 = nums2;
            nums2 = tmp;
        }
        int m = nums1.length;
        int n = nums2.length;
        int[] a = new int[m + 2];
        int[] b = new int[n + 2];
        a[0] = b[0] = Integer.MIN_VALUE;
        a[m + 1] = b[n + 1] = Integer.MAX_VALUE;
        System.arraycopy(nums1, 0, a, 1, m);
        System.arraycopy(nums2, 0, b, 1, n);

        int i = 0;
        int j = (m + n + 1) / 2;
        while (true) {
            if (a[i] <= b[j + 1] && a[i + 1] > b[j]) {
                int max1 = Math.max(a[i], b[j]);
                int min2 = Math.min(a[i + 1], b[j + 1]);
                return (m + n) % 2 > 0 ? max1 : (max1 + min2) / 2.0;
            }
            i++;
            j--;
        }
    }
}
结论

这段代码通过二分查找高效地找出了中位数,时间复杂度为 O(log(min(n, m))),避免了合并数组的高复杂度操作。这种方法是求解两个已排序数组中位数的最佳方案。

希望这篇文章对你理解和应用该算法有所帮助!

相关推荐
skytier32 分钟前
Construct内报错和定位解决
算法
skytier36 分钟前
Ascend print数据落盘使用
算法
etcix1 小时前
dmenux.c: integrate dmenu project as one file
c语言·前端·算法
papership1 小时前
【入门级-算法-6、排序算法:选择排序】
数据结构·算法·排序算法
汉克老师1 小时前
第十四届蓝桥杯青少组C++选拔赛[2023.2.12]第二部分编程题(4、最大空白区)
c++·算法·蓝桥杯·蓝桥杯c++·c++蓝桥杯
共享家95272 小时前
优先搜索(DFS)实战
算法·leetcode·深度优先
一只懒洋洋2 小时前
中值滤波、方框滤波、高斯滤波、均值滤波、膨胀、腐蚀、开运算、闭运算
算法·均值算法
shellvon2 小时前
你怎么被识别的?从TLS到Canvas的设备追踪术
后端·算法
薛定谔的算法2 小时前
JavaScript栈的实现与应用:从基础到实战
前端·javascript·算法
羚羊角uou2 小时前
【Linux】匿名管道和进程池
linux·c++·算法