📅  最后修改于: 2023-12-03 15:28:37.123000             🧑  作者: Mango
这道题目出现在 1997 年 GATE 计算机科学考试中,属于算法和数据结构部分。问题描述如下:
有两个有序列表 A 和 B,每个列表有 n 个元素。请编写一个算法,找到这两个列表合并之后的中位数。要求算法的时间复杂度为 O(log n)。
以下是一个 Python 代码示例,实现了上述功能。
def find_median_sorted_arrays(nums1, nums2):
"""
给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。
请找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m+n))。
"""
# 让 nums1 始终指向较短的数组,减小时间复杂度
if len(nums1) > len(nums2):
nums1, nums2 = nums2, nums1
m, n = len(nums1), len(nums2)
# 如果任何一方为空,则返回另一方的中位数
if m == 0:
return nums2[n // 2] if n % 2 == 1 else (nums2[n // 2] + nums2[n // 2 - 1]) / 2
if n == 0:
return nums1[m // 2] if m % 2 == 1 else (nums1[m // 2] + nums1[m // 2 - 1]) / 2
# 定义两个指针在两个数组中移动,找到中间位置
start, end = 0, m
while start <= end:
i = (start + end) // 2
j = (m + n + 1) // 2 - i
if i < m and nums2[j-1] > nums1[i]:
start = i + 1
elif i > 0 and nums1[i-1] > nums2[j]:
end = 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
以上代码通过二分查找算法找到了两个有序数组合并后的中位数,时间复杂度为 O(log n),达到题目所要求的要求。
可以下载 Jupyter Notebook 在本地运行,查看完整的实现和执行过程。