1. 问题背景与核心挑战
这道力扣经典难题要求我们在两个已排序的数组中找到合并后的中位数。看似简单的需求背后隐藏着几个关键难点:首先,题目要求时间复杂度必须控制在O(log(m+n)),这直接排除了暴力合并的解法;其次,两个数组长度可能差异很大,需要考虑各种边界情况;最重要的是,如何在有序数组中实现对数级复杂度,这自然指向了二分查找的变种应用。
我在第一次遇到这个问题时,尝试了直接合并后取中位数的暴力解法,结果在长数组测试用例上超时。后来经过反复推敲,才理解到这道题的精髓在于将中位数查找转化为寻找第k小元素的通用解法,而二分查找正是实现这一目标的最佳工具。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 算法思路拆解
2.1 中位数本质与问题转化
中位数在统计学上表示将数据集分成两个相等部分的数值。对于合并后的数组,当总长度为奇数时,中位数就是中间那个数;当长度为偶数时,则是中间两个数的平均值。这个定义提示我们可以将问题转化为"寻找第k小的数"的通用问题。
具体来说:
- 总长度奇数:k = (m+n+1)/2
- 总长度偶数:需要找k1=(m+n)/2和k2=(m+n)/2+1两个位置
这种转化使得我们可以用统一的二分查找框架处理两种情况,大大简化了问题复杂度。
2.2 二分查找的变种应用
传统二分查找是在单个有序数组中进行的,而本题需要在两个数组中协同查找。核心思路是:
- 始终保持较短的数组在前,这样可以减少二分次数
- 在较短的数组中进行二分,确定一个分割点
- 根据中位数性质,在较长数组中找到对应的分割点
- 检查分割点是否满足中位数条件
- 根据比较结果调整二分区间
这种协同二分的关键在于理解分割点的四个关键值:
- nums1的左半部分最大值left1
- nums1的右半部分最小值right1
- nums2的左半部分最大值left2
- nums2的右半部分最小值right2
当中位数条件满足时,这四个值之间必须满足特定的排序关系。
3. 详细实现步骤
3.1 初始准备与边界处理
首先处理几个特殊情况可以简化后续逻辑:
- 确保nums1是较短的数组,如果不是则交换
- 处理其中一个数组为空的情况
- 处理查找第1小元素的情况(直接比较两个数组首元素)
python复制def findMedia
