要求时间复杂度log(m+n)
官方题解很到位
"""
二分。
找到切割点
切割点 满足 left_max <= right_min
"""
class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
return self.median(nums1, nums2)
def median(self, A, B):
m, n = len(A), len(B)
if m > n:
A, B, m, n = B, A, n, m
if n == 0:
raise ValueError
#第一个列表的 切割点i,
imin, imax, half_len = 0, m, (m + n + 1) // 2
while imin <= imax:
i = (imin + imax) // 2 #中间
j = half_len - i # 获取第二个数组的切割点j
if i < m and B[j-1] > A[i]:
"""
A1, A2 |i| A3, A4
B1, B2 |j| B3,B4
如果A3 <B2 表示 i 小了
"""
# i is too small, must increase it
imin = i + 1
elif i > 0 and A[i-1] > B[j]:
"""
A1, A2 |i| A3, A4
B1, B2 |j| B3,B4
如果A2 > B3 表示 i 大了
"""
# i is too big, must decrease it
imax = i - 1
else:
#切割点满足 left_集合元素 <= right_集合元素
# i is perfect
if i == 0: max_of_left = B[j-1]
elif j == 0: max_of_left = A[i-1]
else: max_of_left = max(A[i-1], B[j-1])
if (m + n) % 2 == 1: # 奇数长度的情况
return max_of_left
if i == m: min_of_right = B[j]
elif j == n: min_of_right = A[i]
else: min_of_right = min(A[i], B[j])
return (max_of_left + min_of_right) / 2.0
"""
A1, A2 |i| A3, A4
B1, B2 |j| B3,B4
切割点i,j必须满足:
B2 <=A3 and A2 <=B3
所以不符合条件的就是[命题的否定]
B2 > A3 or A2 > B3
"""