算法寻找两个正序数组的中位数
寻找两个正序数组的中位数是一个经典的算法问题,它不仅考验了对数组操作的理解,还涉及到了二分查找和边界条件处理等高级技巧。本文将详细介绍几种高效的算法来解决这个问题,并通过具体的代码示例帮助读者理解和掌握这些方法。
基本概念和作用说明
中位数的定义
中位数是指将一个有序列表分成两个相等部分的那个数。如果列表的长度是奇数,中位数就是中间的那个数;如果列表的长度是偶数,中位数则是中间两个数的平均值。
问题描述
给定两个正序数组 nums1
和 nums2
,我们需要找到这两个数组合并后的中位数。假设两个数组的总长度为 m + n
,我们需要在 O(log(min(m, n))) 的时间复杂度内完成这个任务。
寻找中位数的算法
示例一:合并排序法
最直观的方法是将两个数组合并成一个有序数组,然后找到中位数。这种方法简单易懂,但时间复杂度为 O((m+n)log(m+n)),不适合大规模数据。
def find_median_sorted_arrays_merge(nums1: list, nums2: list) -> float:
"""
使用合并排序法找到两个正序数组的中位数。
参数:
nums1 (list): 第一个正序数组
nums2 (list): 第二个正序数组
返回:
float: 合并后数组的中位数
"""
merged = sorted(nums1 + nums2)
total_length = len(merged)
if total_length % 2 == 0:
return (merged[total_length // 2 - 1] + merged[total_length // 2]) / 2
else:
return merged[total_length // 2]
# 测试函数
nums1 = [1, 3]
nums2 = [2]
print(find_median_sorted_arrays_merge(nums1, nums2)) # 输出: 2.0
示例二:二分查找法
二分查找法是一种更高效的方法,可以在 O(log(min(m, n))) 的时间复杂度内找到中位数。核心思想是在两个数组中分别找到一个分割点,使得左边的元素都不大于右边的元素。
def find_median_sorted_arrays_binary_search(nums1: list, nums2: list) -> float:
"""
使用二分查找法找到两个正序数组的中位数。
参数:
nums1 (list): 第一个正序数组
nums2 (list): 第二个正序数组
返回:
float: 合并后数组的中位数
"""
if len(nums1) > len(nums2):
nums1, nums2 = nums2, nums1
x, y = len(nums1), len(nums2)
low, high = 0, x
while low <= high:
partitionX = (low + high) // 2
partitionY = (x + y + 1) // 2 - partitionX
maxX = float('-inf') if partitionX == 0 else nums1[partitionX - 1]
minX = float('inf'