力扣—寻找两个正序数组的中位数(Median of Two Sorted Arrays Java)
发布日期:2021-05-08 04:05:01 浏览次数:11 分类:精选文章

本文共 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)),满足题目的要求。这种方法避免了直接合并数组的高时间复杂度,并且能够处理大规模数据。

    上一篇:方法重写、方法覆盖、方法重载是什么意思,它们的区别?
    下一篇:Cookie和Session(保存信息和状态)

    发表评论

    最新留言

    初次前来,多多关照!
    [***.217.46.12]2025年04月07日 12时58分16秒

    关于作者

        喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
    -- 愿君每日到此一游!

    推荐文章