给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。
请你找出这两个正序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。
你可以假设 nums1 和 nums2 不会同时为空。
示例 1:
nums1 = [1, 3]
nums2 = [2]
则中位数是 2.0
示例 2:
nums1 = [1, 2]
nums2 = [3, 4]
则中位数是 (2 + 3)/2 = 2.5
解题模板:
Python 3:
class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
众所周知,List.sort()函数可以实现排序,只不过时间复杂度为 O( (N + M) * log(N + M) ),通过位序直接返回结果。
基本方法:类似两列表有序合并的实现算法,对比两指针所指元素,数值小的指针后移,到达相应次数停止,返回结果。
中间点的位置就在(len1 + len2 + 1) // 2
考虑一般情况下,第一个序列存在一个数,其左边都是小于中位数,右边都大于;第二个序列也是一样。这两个数的序列分别在 mid1 和 mid2。如果 mid2 左侧的数比 mid1 对应的数都大,那么第一行的中间靠左;如果 mid2 左侧的数比 mid1 大,那么选第二行的小的和第一行大的数,这样的数更接近。把第一行的中间往右,即二分查找的更新 left,反之更新 right。
class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
result = nums1 + nums2
result.sort()
if len(result) % 2 != 0:
return result[len(result) // 2]
else:
right = len(result) // 2
left = right - 1
return (result[left] + result[right]) / 2
时间复杂度O( (N + M) * log(N + M) )
空间复杂度O(N + M)
class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
length = len(nums1) + len(nums2)
if length % 2 == 0:
mid = length // 2 - 1
a, b = 0, 0
for i in range(mid):
if a in range(len(nums1)) and b in range(len(nums2)):
if nums1[a] <= nums2[b]:
a += 1
else:
b += 1
elif a in range(len(nums1)):
a += 1
else:
b += 1
if a in range(len(nums1)) and b in range(len(nums2)):
if nums1[a] <= nums2[b]:
if a + 1 in range(len(nums1)):
if nums1[a+1] <= nums2[b]:
return (nums1[a] + nums1[a+1]) / 2
return (nums1[a] + nums2[b]) / 2
else:
if b + 1 in range(len(nums2)):
if nums2[b + 1] <= nums1[a]:
return (nums2[b] + nums2[b + 1]) / 2
return (nums2[b] + nums1[a]) / 2
elif a in range(len(nums1)):
return (nums1[a] + nums1[a+1]) / 2
else:
return (nums2[b] + nums2[b+1]) / 2
else:
mid = length // 2
a, b = 0, 0
for i in range(mid):
if a in range(len(nums1)) and b in range(len(nums2)):
if nums1[a] <= nums2[b]:
a += 1
else:
b += 1
elif a in range(len(nums1)):
a += 1
else:
b += 1
if a in range(len(nums1)) and b in range(len(nums2)):
return nums1[a] if nums1[a] <= nums2[b] else nums2[b]
elif a in range(len(nums1)):
return nums1[a]
else:
return nums2[b]
时间复杂度O(N + M)
空间复杂度O(1)
class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
len_1, len_2 = len(nums1), len(nums2)
if len_1 > len_2:
nums1, nums2, len_1, len_2 = nums2, nums1, len_2, len_1
min_, max_, mid_ = 0, len_1, (len_1 + len_2 + 1) / 2
while min_ <= max_:
i = (min_ + max_) // 2
j = int(mid_ - i)
if i < len_1 and nums2[j-1] > nums1[i]:
min_ = i + 1
elif i > 0 and nums1[i-1] > nums2[j]:
max_ = i - 1
else:
if i == 0:
left = nums2[j-1]
elif j == 0:
left = nums1[i-1]
else:
left = max(nums1[i-1], nums2[j-1])
if (len_1 + len_2) % 2 == 1:
return left
if i == len_1:
right = nums2[j]
elif j == len_2:
right = nums1[i]
else:
right = min(nums1[i], nums2[j])
return (left + right) / 2.0
时间复杂度O( log(N + M) )
空间复杂度O(1)