网站首页 > 技术文章 正文
题目:寻找两个正序数组的中位数
给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
算法的时间复杂度应该为 O(log(m+n)) 。
示例 1:
输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
解释:合并数组 = [1,2,3] ,中位数 2
示例 2:
输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5
一、问题分析
本题要求找出两个正序数组的中位数,并且算法的时间复杂度要达到。中位数是将一个集合划分为两个长度相等的子集,其中一个子集中的元素总是大于另一个子集中的元素。
常规思路
最直接的方法是将两个数组合并成一个有序数组,然后根据合并后数组的长度是奇数还是偶数来计算中位数。不过这种方法的时间复杂度是,不符合本题要求。
优化思路
为了达到 的时间复杂度,我们可以采用二分查找的方法。其核心思想是在较短的数组上进行二分查找,以此确定合适的分割点,从而将两个数组划分为左右两部分,保证左边部分的所有元素都小于等于右边部分的所有元素。
二、算法步骤
- 确定较短数组:为了让二分查找在较短的数组上进行,首先要确定哪个数组更短。
- 二分查找分割点:在较短的数组上进行二分查找,找到一个分割点,使得两个数组被划分为左右两部分,并且满足左边部分的元素个数等于右边部分的元素个数(或者左边比右边多一个元素)。
- 检查分割点是否满足条件:判断分割点是否满足左边部分的所有元素都小于等于右边部分的所有元素。若不满足,就调整二分查找的范围。
- 计算中位数:当找到合适的分割点后,根据合并后数组的长度是奇数还是偶数来计算中位数。
三、Python 代码实现
下面是实现寻找两个正序数组中位数功能的代码:
def find_median_sorted_arrays(nums1, nums2):
# 确保 nums1 是较短的数组,这样可以减少二分查找的范围
if len(nums1) > len(nums2):
nums1, nums2 = nums2, nums1
m, n = len(nums1), len(nums2)
# 二分查找的左右边界
left, right = 0, m
half_len = (m + n + 1) // 2
while left <= right:
# 计算 nums1 的分割点
partition1 = (left + right) // 2
# 计算 nums2 的分割点
partition2 = half_len - partition1
# 计算 nums1 左边部分的最大值
max_left1 = float('-inf') if partition1 == 0 else nums1[partition1 - 1]
# 计算 nums1 右边部分的最小值
min_right1 = float('inf') if partition1 == m else nums1[partition1]
# 计算 nums2 左边部分的最大值
max_left2 = float('-inf') if partition2 == 0 else nums2[partition2 - 1]
# 计算 nums2 右边部分的最小值
min_right2 = float('inf') if partition2 == n else nums2[partition2]
# 检查分割点是否满足条件
if max_left1 <= min_right2 and max_left2 <= min_right1:
# 如果合并后数组的长度是奇数,中位数就是左边部分的最大值
if (m + n) % 2 == 1:
return max(max_left1, max_left2)
# 如果合并后数组的长度是偶数,中位数是左边部分的最大值和右边部分的最小值的平均值
else:
return (max(max_left1, max_left2) + min(min_right1, min_right2)) / 2
# 如果分割点不满足条件,调整二分查找的范围
elif max_left1 > min_right2:
right = partition1 - 1
else:
left = partition1 + 1
# 如果代码执行到这里,说明输入的数组不是有序的,抛出异常
raise ValueError("Input arrays are not sorted.")
# 测试示例
nums1 = [1, 3]
nums2 = [2]
print(find_median_sorted_arrays(nums1, nums2)) # 输出: 2.0
nums1 = [1, 2]
nums2 = [3, 4]
print(find_median_sorted_arrays(nums1, nums2)) # 输出: 2.5
四、复杂度分析
- 时间复杂度:由于使用了二分查找,且每次查找都会将搜索范围缩小一半,所以时间复杂度为 ,满足 的要求。
- 空间复杂度:只使用了常数级的额外空间,因此空间复杂度为 。
通过上述分析和代码实现,我们可以高效地找出两个正序数组的中位数。
猜你喜欢
- 2025-05-16 实用主义 Python 一行命令走天涯
- 2025-05-16 Python的random模块常用方法
- 2025-05-16 python入门-day21-周末复习
- 2025-05-16 今天我学习了Python数据统计分析教程,把笔记分享出来
- 2025-05-16 零基础入门 Python 内置函数:从基础到进阶的实用指南
- 2025-05-16 交互式操作 Excel,所见即所得:Python xlwings 库详解
- 2025-05-16 R语言raster包遍历文件夹并计算大量栅格数据平均值
- 2025-05-16 Python入门-Day 18:Pandas 基础
- 2025-05-16 Python数据分析(四)
- 2025-05-16 Python函数实用教程
- 05-25Python 3.14 t-string 要来了,它与 f-string 有何不同?
- 05-25Python基础元素语法总结
- 05-25Python中的变量是什么东西?
- 05-25新手常见的python报错及解决方案
- 05-2511-Python变量
- 05-2510个每个人都是需要知道Python问题
- 05-25Python编程:轻松掌握函数定义、类型及其参数传递方式
- 05-25Python基础语法
- 257℃Python短文,Python中的嵌套条件语句(六)
- 257℃python笔记:for循环嵌套。end=""的作用,图形打印
- 256℃PythonNet:实现Python与.Net代码相互调用!
- 251℃Python操作Sqlserver数据库(多库同时异步执行:增删改查)
- 251℃Python实现字符串小写转大写并写入文件
- 106℃原来2025是完美的平方年,一起探索六种平方的算吧
- 91℃Python 和 JavaScript 终于联姻了!PythonMonkey 要火?
- 81℃Ollama v0.4.5-v0.4.7 更新集合:Ollama Python 库改进、新模型支持
- 最近发表
- 标签列表
-
- python中类 (31)
- python 迭代 (34)
- python 小写 (35)
- python怎么输出 (33)
- python 日志 (35)
- python语音 (31)
- python 工程师 (34)
- python3 安装 (31)
- python音乐 (31)
- 安卓 python (32)
- python 小游戏 (32)
- python 安卓 (31)
- python聚类 (34)
- python向量 (31)
- python大全 (31)
- python次方 (33)
- python桌面 (32)
- python总结 (34)
- python浏览器 (32)
- python 请求 (32)
- python 前端 (32)
- python验证码 (33)
- python 题目 (32)
- python 文件写 (33)
- python中的用法 (32)