There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
You may assume nums1 and nums2 cannot be both empty.
Example 1:
nums1 = [1, 3]
nums2 = [2]
The median is 2.0
Example 2:
nums1 = [1, 2]
nums2 = [3, 4]
The median is (2 + 3)/2 = 2.5
题目大意:题意较简单,就是找出两个排好序的数组合并后的中位数。
解题思路:由于本题要求时间复杂度为O(log(m+n)),所以自然想到二分搜索,但是问题在于搜索什么?二分搜索最重要的就是搜索停止条件,以及什么情况下向左转移什么情况下向右。
本题的突破口在于中位数,中位数的含义就是将数组从小到大排列后,中位数左右的数的数量是相同的。两个数组的元素个数是确定的,这样最后得到的中位数左右的元素个数也是确定的,我们选择其中一个数组进行二分搜索,搜索该数组中有多少元素在最终的中位数的左边,左边的个数确定了右边自然也确定了,同时第二个数组中的左右边的个数也确定了。有了这个思路就可以对两个数组中元素较少的数组进行搜索(主要是为了降低复杂度),这样整个算法的时间复杂度就是O(log(min(m, n)))。
代码:
def findMedianSortedArrays(nums1, nums2):
# 先找出两个数组中元素较少的数组,默认情况下认为nums1元素个数少于nums2
if len(nums1) > len(nums2):
temp = nums2
nums2 = nums1
nums1 = temp
# assert len(nums1) <= len(nums2)
n1, n2 = len(nums1), len(nums2)
if n1 == 0:
nums2.sort()
# print("num2", nums2)
if n2 % 2 == 1:
return nums2[(n2 - 1) // 2]
else:
return (nums2[n2 // 2 - 1] + nums2[n2 // 2]) / 2.0
# nums1 n1个元素, nums2 n2个元素
# 合并后分割线的左边应该有 (n1 + n2 + 1) / 2个元素
# 例如 1 2 | 3 "|" 为中位线分割线 3个数分割线左边有2个
# 1 2 | 3 4 4个数分割线左边有2个
# 所以现在的目的就是在nums1数组中搜索正确的分割线
left, right = 0, len(nums1) # 搜索边界,含义就是nums1中被归在左边的元素的个数的左右边界
while left <= right:
nums1_left = (left + right) // 2 # nums1中位于分割线左边的数字的个数
nums2_left = (n1 + n2 + 1) // 2 - nums1_left # nums2中位于分割线左边的数字的个数
nums1_left_value = -float("inf") if nums1_left == 0 else nums1[nums1_left - 1] # 有可能0个,这时填补-inf
nums2_left_value = -float("inf") if nums2_left == 0 else nums2[nums2_left - 1]
nums1_right_value = float("inf") if nums1_left >= n1 else nums1[nums1_left]
nums2_right_value = float("inf") if nums2_left >= n2 else nums2[nums2_left]
if nums1_left_value <= nums2_right_value and nums2_left_value <= nums1_right_value:
left_max = max(nums1_left_value, nums2_left_value)
right_min = min(nums1_right_value, nums2_right_value)
if (n1 + n2) % 2 == 0:
return (left_max + right_min) / 2.0
else:
return left_max
elif nums1_left_value > nums2_right_value:
right = nums1_left - 1
else:
left = nums1_left + 1
examples = [
[[1], [2]],
[[1, 2], [-1, 3]],
[[1, 2], [3]],
[[1, 2], [3, 4, 5]],
[[1], [2, 3, 5, 6]],
[[1, 3], [2]],
[[1, 2], [3, 4]],
[[1], [2, 3, 4]]
]
for num1, num2 in examples:
print(num1, num2, ":")
print(findMedianSortedArrays(num1, num2), findMedianSortedArrays([], num1 + num2))
参考链接:
https://www.youtube.com/watch?v=LPFhl65R7ww&t=479s
本文介绍了一种高效算法,用于查找两个已排序数组的中位数,时间复杂度为O(log(min(m,n)))。通过二分搜索确定中位数的位置,确保两边元素数量相等。
670

被折叠的 条评论
为什么被折叠?



