题目描述
给定两个大小分别为 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
示例 3:
输入:nums1 = [0,0], nums2 = [0,0]
输出:0.00000
解题思路1: 2个数组同时遍历法
- 假设2个数组元素个数总数为 2n, 那么中位数的idx=n, 我们给2个数组分别一个idx进行遍历, 哪个数组的当前元素小, 我们就让idx后移, 直到2个idx的和为n. 这样就找到了中位数
- 因为中位数分奇偶的情况, 所以我们还需要做特殊的处理:
- 如果是奇数的情况, 我们遍历的次数为: n+1 次, 取最后一次结果返回
- 如果是偶数情况, 我们最终也是需要遍历 n+1 次, 取最后2次结果的和/2返回
- 根据这样的现象, 我们可以将奇数/偶数的遍历统一处理. 用一个值保存当前遍历的结果, 一个值保存上一次遍历的结果, 这样在偶数的情况我们就能拿到2个结果去处理
示例代码
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
count = (len(nums1) + len(nums2))
h1 = h2 = id1 = id2 = 0
while (id1 + id2) <= count // 2:
h1 = h2
if id1 < len(nums1) and (id2 >= len(nums2) or nums1[id1] < nums2[id2]):
h2 = nums1[id1]
id1 += 1
else:
h2 = nums2[id2]
id2 += 1
if count & 1 == 0:
return (h1 + h2) / 2
else:
return h2
注意
- 这个题解能 Accepted, 但是不满足题意时间复杂度应该为 O(log (m+n))的要求. 所以下一篇会介绍满足要求的题解
- 这个题目其实是2个有序数组排序后第K个元素题解的特殊情况, K = (l1 + l2)/2