📅  最后修改于: 2023-12-03 15:23:03.875000             🧑  作者: Mango
给定两个已排序的数组A1和A2,大小为m和n。我们需要在O(logn)的时间复杂度内找到这两个数组的中位数。
一个简单直接的思路是将A1和A2合并成一个已排序的数组B,然后找到B的中位数。但这种方法需要O(m+n)的时间复杂度,不满足题目要求。
我们可以尝试使用二分查找的思想,将问题转化为在A2中查找一个位置i,使得:
这样我们就将问题转化为在A2中查找目标位置i的问题。
为了方便讨论,我们假设m<=n,那么可以将i分为两部分:i在A2中的位置j和i在A1中的位置k=i-j-1。
由于A1和A2都是有序的,如果我们已知j,那么可以通过比较A2[j-1]、A2[j]、A1[k]、A1[k+1]四个数的大小关系来判断i是否是中位数。
完整的代码实现如下:
class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
m, n = len(nums1), len(nums2)
if m > n:
nums1, nums2, m, n = nums2, nums1, n, m
imin, imax, half_len = 0, m, (m+n+1) // 2
while imin <= imax:
i = (imin + imax) // 2
j = half_len - i
if i < m and nums2[j-1] > nums1[i]:
imin = i + 1
elif i > 0 and nums1[i-1] > nums2[j]:
imax = i - 1
else:
if i == 0: max_of_left = nums2[j-1]
elif j == 0: max_of_left = nums1[i-1]
else: max_of_left = max(nums1[i-1], nums2[j-1])
if (m + n) % 2 == 1:
return max_of_left
if i == m: min_of_right = nums2[j]
elif j == n: min_of_right = nums1[i]
else: min_of_right = min(nums1[i], nums2[j])
return (max_of_left + min_of_right) / 2