当前位置: 首页 > news >正文

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

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

算法的时间复杂度应该为 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. 计算中位数
    一旦找到了合适的切分点,就可以根据数组的总长度来计算中位数。如果总长度是奇数,返回左边部分的最大值;如果是偶数,返回左边最大值和右边最小值的平均值。

算法实现
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))),避免了合并数组的高复杂度操作。这种方法是求解两个已排序数组中位数的最佳方案。

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

相关文章:

  • 一文了解zookeeper
  • Node.js HTTP模块详解:创建服务器、响应请求与客户端请求
  • Sora平替|有言AI数字人视频生成工具“极简实操”
  • arduino扩展:Arduino Mega 控制 32 个舵机(参考表情机器人)
  • 【Map vs Set】:Java数据存储的“双子星”对决
  • RabbitMQ配置SSL证书
  • 在 Crates.io 上发布 Crate 的全流程指南
  • C++ 完美转发:泛型编程中的参数无损传递
  • 为AI聊天工具添加一个知识系统 之103 详细设计之44 自性三藏 之4 祖传代码 之2
  • Java 大视界 -- 量子计算时代 Java 大数据的潜在变革与应对策略(88)
  • 深度学习框架探秘|Keras 应用案例解析以及 Keras vs TensorFlow vs PyTorch
  • ‌CBA认证‌(业务架构师认证)简介---适用人群、考试内容与形式、含金量与职业前景,以及‌CBA、TOGAF认证对比表格
  • 什么是弧形光源
  • 【认证授权FAQ】HP Anyware LLS服务器常用命令
  • 【第2章:神经网络基础与实现——2.4 实战案例:使用TensorFlow或PyTorch实现简单的MLP模型】
  • 硬件学习笔记--42 电磁兼容试验-6 传导差模电流干扰试验介绍
  • 库里存储的数据有大量回车时,该如何进行存取
  • 机柜机箱制冷风扇在使用过程中突然停止运转的原因
  • 【教程】比亚迪车机接入AI大模型语音助手
  • Oracle 12c 并发统计信息收集功能:技术解析与实践指南
  • “马上涨价”再到“吞下关税”,美政策让沃尔玛“输两次”
  • 当“小铁人”遇上青浦,看00后如何玩转长三角铁三
  • 《歌手》回归,人均技术流,00后整顿职场
  • 中欧互动中的合作与分歧:务实需求将克服泛安全化的“政治钟摆”
  • 上海制造佳品汇大阪站即将启幕,泡泡玛特领潮出海
  • 南方降水频繁暴雨连连,北方高温再起或现40°C酷热天气