
力扣—寻找两个正序数组的中位数(Median of Two Sorted Arrays Java)
确定合并后的数组长度:计算 nums1 和 nums2 的长度之和 m + n。 判断奇偶性:根据合并后的数组长度是否为奇数或偶数,决定返回哪一个数或两个数的平均值。 二分查找切分点:使用二分查找在两个数组中找到合适的切分位置,使得这两个数组的切分点满足中位数的条件。
发布日期: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)) 时间复杂度,因此需要更高效的方法。
解决思路
采用二分查找的方法来找到合适的切分点,使得两个数组的切分位置满足中位数的条件。具体步骤如下:
方法实现
为了实现这个思路,我们可以编写一个递归函数 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)),满足题目的要求。这种方法避免了直接合并数组的高时间复杂度,并且能够处理大规模数据。
发表评论
最新留言
初次前来,多多关照!
[***.217.46.12]2025年04月07日 12时58分16秒
关于作者

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