博客
关于我
力扣—寻找两个正序数组的中位数(Median of Two Sorted Arrays Java)
阅读量:369 次
发布时间:2019-03-05

本文共 2494 字,大约阅读时间需要 8 分钟。

要解决给定两个正序数组 nums1 和 nums2,找到它们合并后的中位数的问题,可以采用二分查找的方法,以确保时间复杂度为 O(log(m+n))。以下是详细的思路和步骤:

问题分析

给定两个有序数组 nums1 和 nums2,要求找到它们合并后的中位数。中位数的定义是:

  • 如果合并后的数组长度为奇数,中位数是中间的那个数;
  • 如果合并后的数组长度为偶数,中位数是中间两个数的平均值。

直接合并两个数组后取中位数的时间复杂度为 O(max(m, n)),这不符合题目要求的 O(log(m + n)) 时间复杂度,因此需要更高效的方法。

解决思路

采用二分查找的方法来找到合适的切分点,使得两个数组的切分位置满足中位数的条件。具体步骤如下:

  • 确定合并后的数组长度:计算 nums1 和 nums2 的长度之和 m + n。
  • 判断奇偶性:根据合并后的数组长度是否为奇数或偶数,决定返回哪一个数或两个数的平均值。
  • 二分查找切分点:使用二分查找在两个数组中找到合适的切分位置,使得这两个数组的切分点满足中位数的条件。
  • 方法实现

    为了实现这个思路,我们可以编写一个递归函数 findKth,用于找到第 k 小的数。这个函数通过二分查找来确定在两个数组中的位置,并根据需要调整 k 的值,最终返回第 k 小的数。

    代码逻辑

    public class Solution {    public double findMedianSortedArrays(int[] nums1, int[] nums2) {        int m = nums1.length;        int n = nums2.length;        int total = m + n;        if (total % 2 != 0) {            return findKth(nums1, nums2, total / 2, 0, m - 1, 0, n - 1);        } else {            int k1 = findKth(nums1, nums2, total / 2, 0, m - 1, 0, n - 1);            int k2 = findKth(nums1, nums2, (total / 2) - 1, 0, m - 1, 0, n - 1);            return (k1 + k2) / 2.0;        }    }    public static int findKth(int[] nums1, int[] nums2, int k, int aStart, int aEnd, int bStart, int bEnd) {        int aLen = aEnd - aStart + 1;        int bLen = bEnd - bStart + 1;        if (aLen == 0) {            return nums2[bStart + k];        }        if (bLen == 0) {            return nums1[aStart + k];        }        if (k == 0) {            return nums1[aStart] < nums2[bStart] ? nums1[aStart] : nums2[bStart];        }        int aMid = aLen * k / (aLen + bLen);        aMid += aStart;        int bMid = k - aMid;        bMid += bStart;        if (nums1[aMid] > nums2[bMid]) {            k -= (bMid - bStart + 1);            aEnd = aMid - 1;            bStart = bMid + 1;        } else {            k -= (aMid - aStart + 1);            bEnd = bMid - 1;            aStart = aMid + 1;        }        return findKth(nums1, nums2, k, aStart, aEnd, bStart, bEnd);    }}

    代码解释

  • findMedianSortedArrays 函数:

    • 计算两个数组的总长度 total。
    • 判断 total 是否为奇数或偶数,决定调用 findKth 函数来找到合适的位置。
    • 如果 total 为奇数,直接返回第 (total / 2) 小的数;如果为偶数,返回中间两个数的平均值。
  • findKth 函数:

    • 递归地在 nums1 和 nums2 中找到第 k 小的数。
    • 计算数组的长度 aLen 和 bLen,以及当前的 k。
    • 如果 aLen 或 bLen 为 0,直接返回另一个数组中的第 k 小的数。
    • 比较当前的 aMid 和 bMid,决定调整 k 的值,并缩小搜索范围。
    • 递归调用 findKth,直到找到第 k 小的数。
  • 优化考虑

    • 递归终止条件:当 aLen 或 bLen 为 0 时,直接返回另一个数组中的第 k 小的数。
    • k 调整逻辑:根据当前 aMid 和 bMid 的值,调整 k 的值以缩小搜索范围。
    • 时间复杂度:通过每次递归将搜索范围大致减半,确保时间复杂度为 O(log(m + n))。

    总结

    通过使用二分查找的方法,可以高效地找到两个有序数组合并后的中位数,时间复杂度为 O(log(m + n)),满足题目的要求。这种方法避免了直接合并数组的高时间复杂度,并且能够处理大规模数据。

    转载地址:http://aygg.baihongyu.com/

    你可能感兴趣的文章
    leetcode 14 最长公共前缀
    查看>>
    做做Java
    查看>>
    C++并发与多线程(一)
    查看>>
    java一些基本程序
    查看>>
    vue-依赖-点击复制
    查看>>
    LeetCode 116填充每个节点的下一个右侧结点指针
    查看>>
    2021-4-28【PTA】【L2-1 包装机 (25 分)】
    查看>>
    Arduino mega2560+MPU6050利用加速度值控制舵机
    查看>>
    紫书——蛇形填数
    查看>>
    A Guide to Node.js Logging
    查看>>
    webwxbatchgetcontact一个神奇的接口
    查看>>
    Edge浏览器:你的的内核我的芯
    查看>>
    【考研英语-基础-简单句】简单句的核心变化_谓语情态
    查看>>
    Jetson AGX Xavier硬件自启动
    查看>>
    统计字符数
    查看>>
    JS 数组的 every()、some() 、filter()、findIndex() 、find()、map()方法
    查看>>
    JS数据类型的判断
    查看>>
    实现一个简易Vue(三)Compiler
    查看>>
    仿小米商城(上)
    查看>>
    自动安装服务2
    查看>>