该题解使用了二分查找的思想。首先确保较短的数组为 nums1,如果不是就交换。然后使用二分查找在 nums1 中找到一个分割点 i,使得 nums1[0...i-1] 和 nums2[0...j-1](j = (m+n+1)//2 - i)的元素个数之和等于 (m+n+1)//2。这样就可以保证左半部分的元素个数等于右半部分或者多一个。最后,根据总元素个数的奇偶性,返回左半部分的最大值或左右部分的最大最小值的平均数作为中位数。
时间复杂度: O(log min(m, n))
空间复杂度: O(1)
class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
m = len(nums1)
n = len(nums2)
if m > n:
# 确保 nums1 是较短的数组
return self.findMedianSortedArrays(nums2, nums1)
total_left = (m + n + 1) // 2
l = 0
r = m
while l < r:
# 在 nums1 中二分查找分割点 i
i = l + (r - l + 1) // 2
j = total_left - i
if nums1[i-1] <= nums2[j]:
l = i
else:
r = i - 1
i = l
j = total_left - i
# 获取左半部分的最大值
left_nums1_max = float('-inf') if i == 0 else nums1[i-1]
left_nums2_max = float('-inf') if j == 0 else nums2[j-1]
# 获取右半部分的最小值
right_nums1_min = float('inf') if i == m else nums1[i]
right_nums2_min = float('inf') if j == n else nums2[j]
if (m + n) % 2 == 1:
# 如果总长度为奇数,中位数就是左半部分的最大值
return max(left_nums1_max, left_nums2_max)
else:
# 如果总长度为偶数,中位数就是左半部分最大值和右半部分最小值的平均值
return (max(left_nums1_max, left_nums2_max) + min(right_nums1_min, right_nums2_min)) / 2