LeetCode findMedianSortedArrays Python3

给定两个有序数组 A 和 B,要求在 O(log(m+n)) 时间复杂度内找到中位数。示例:A = [1,3], B = [2],输出 2.0;A = [1,2], B = [3,4],输出 2.5。解决方案利用二分查找,找到分割点 i 和 j 使等长划分满足最值关系,确保 A[i-1] < B[j] 且 B[j-1] < A[i],最后处理边界情况,输出中位数。" 117333446,10997635,Spring框架中的依赖注入详解,"['Spring', '依赖注入', 'XML配置', 'Java']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述:给定两个大小为 m 和 n 的有序数组 A 和 B 。找出这两个有序数组的中位数,并且要求算法时间复杂度为 O(log(m+n))。可以假设这两个数组不会同时为空。
示例 1:
输入: A = [1,3], B = [2]
输出: 2.0
示例 2:
输入: A = [1,2], B = [3,4]
输出: (2+3) / 2 = 2.5

其实如果没有时间复杂度的要求,这个问题用 Python 实在是太简单了,感觉有点像作弊:

def findMedianSortedArrays(A, B):
	res = []
	res.expand(A)
	res.expand(B)
	res = sorted(res)
	if len(res) % 2 == 0:
		half = len(res) // 2
		return (res[half-1] + res[half]) / 2.0
	else:
		return res[len(res)//2] / 1.0

但是这个代码在效率上是不合格的,因为只是使用 sorted 函数 O 就已经爆掉了。看到给出的示例大概是这样的:

def findMedianSortedArrays(A, B):
	m, n = len(A), len(B)
	if m > n:
		A, B, m, n = B, A, n, m
	if n < 1:
		raise ValueError
	
	imin, imax, half = 0, m, (m+n+1) // 2
	while imin <= imax:
		i = (imin+imax) // 2
		j = half - i
		if i < m and A[i] < B[j-1]:
			imin = i + 1
		elif j > 0  and B[j] < A[i-1]:
			imax = i - 1
		else:
			if i == 0: max_left = B[j-1]
			elif j == 0: max_left = A[i-1]
			else: max_left = max(A[i-1], B[j-1])

			if (m+n) % 2 != 0:
				return max_left / 1.0
			else:
				if i == m: min_right = B[j]
				elif j == n: min_right = A[i]
				else: min_right = min(A[i], B[j])
				return (max_left+min_right) / 2.0

官方给出的示例解释非常专业,所以我看了很久才看懂。这里简单解释一下这个算法的思想:

  • 所谓中位数的含义就是将一个集合划分成两个等长的子集,使得其中一个子集中的最大值小于另一个子集中的最小值,这样就得到了中位数的两个判据:等长划分、最值关系
  1. 首先找到两个分割点 i 和 j 分别分割 A 和 B, 保证分割后的 len(Aleft)+len(Bleft)len(A_{left}) + len(B_{left})len(Aleft)+len(Bleft)len(Aright)+len(Bright)len(A_{right}) + len(B_{right})len(Aright)+len(Bright)相等,这点由代码的10、11行保证,即保证了等长划分。
  2. 之后要保证两部分最值间的关系,因为原始的 A 和 B 都是有序的,所以只需沿着划分点比较就可以了,这省了很多事。最后确定的划分点应该满足
    A[i−1]&lt;B[j],B[j−1]&lt;A[i]A[i-1]&lt;B[j],B[j-1]&lt;A[i]A[i1]<B[j]B[j1]<A[i]
    发现不满足,就根据不满足的情况调整 i 的搜索区间,就是代码中的二分查找。
  3. 最后解决边界问题,即 i = 0, m,j = 0, n 的情况,分类讨论一下即可。最后就找到了左部分的最大值和右部分的最小值,输出平均数作为返回值。
### LeetCode Top 200 Popular Problems LeetCode提供了一个广泛的问题库,其中包含了各种难度级别的算法挑战。对于希望提升编程技能或准备技术面试的人来说,专注于Top 200热门问题是很有帮助的[^1]。 这些题目涵盖了多个领域,包括但不限于数组操作、字符串处理、链表管理、树结构遍历以及动态规划等复杂逻辑设计。通过解决这些问题,可以有效提高解决问题的能力并熟悉常见的数据结构和算法模式[^2]。 为了更好地理解如何应对这类问题,下面给出了一部分属于LeetCode上非常受欢迎的经典案例列表: #### 数据结构基础 - **Two Sum** 给定一个整数数组`nums` 和一个目标值 `target` ,请找出数组中和为目标值的那两个整数,并返回他们的数组下标。 ```python def twoSum(nums, target): hashmap = {} for i in range(len(nums)): complement = target - nums[i] if complement in hashmap: return [hashmap[complement], i] hashmap[nums[i]] = i ``` - **Add Two Numbers** 将两个非空链表表示的两位正整数相加,并以相同形式返回两数之和的结果链表。 #### 字符串与数组 - **Median of Two Sorted Arrays** 存在一个由两个已排序升序序列组成的集合A和B,求这两个有序数组合并后的中间值。 ```python def findMedianSortedArrays(nums1, nums2): merged = sorted(nums1 + nums2) n = len(merged) median = (merged[n//2] + merged[(n-1)//2]) / 2 return median ``` - **Longest Substring Without Repeating Characters** 寻找给定字符串中最长不含重复字符子串长度。 #### 动态规划 - **Climbing Stairs** 假设你正在爬楼梯。需要n阶才能到达楼顶。每次可以选择爬1级或者2级台阶。计算共有多少种不同的方法可以从底部爬上顶部。 ```python def climbStairs(n): if n == 1 or n == 2: return n first, second = 1, 2 for _ in range(3, n+1): third = first + second first, second = second, third return second ``` 以上仅列举了几道具有代表性的习题;实际上,在LeetCode平台上还有许多其他类型的经典难题等待探索者去解锁更多技巧与策略。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值