给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。
请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。
你可以假设 nums1 和 nums2 不会同时为空。
示例 1:
nums1 = [1, 3]
nums2 = [2]
则中位数是 2.0
示例 2:
nums1 = [1, 2]
nums2 = [3, 4]
则中位数是 (2 + 3)/2 = 2.5
这个题目是不会做的,然后看了题解,这里整理一下思路。
假设数组A和B的长度分别为m, n, 我们首先可以得到如下结论:
- 如果 (m + n) % 2 == 0, 返回的是排序后index1 = (m + n) // 2 和 index2 = (m + n) // 2 - 1 的平均数
- 如果 (m + n) % 2 == 1, 返回的是排序后index = (m + n) // 2 的数
解题思路主要利用了中位数的特性:
将一个集合划分为两个长度相等的子集,其中一个子集中元素总是大于另一个子集中的元素。
假设数组 A 和 B,分别被分解成了两部分,
-
A[0], A[1], … , A[i-1] | A[i], … , A[m-1]
-
B[0], B[1], …, B[j-1] | B[j], … , B[n-1]
i = 0, 1, 2, … , m; i = 0表示A的左半部分为空, i = m表示 A的右半部分为空; 同理 j = 0, 1, 2, …, n, j = 0表示B的左半部分为空, j = n表示 B的右半部分为空.
如果使其成为中位数,则需满足:
-
i+j==m−i+n−j+δi + j == m - i + n - j + \deltai+j==m−i+n−j+δ, m+nm+nm+n为偶数时, δ=0\delta = 0δ=0,m+nm+nm+n为奇数时, δ=1\delta = 1δ=1
i=(m+n+δ)/2−j=(m+n+1)//2−ji = (m + n + \delta) / 2 - j = (m + n + 1) // 2 - ji=(m+n+δ)/2−j=(m+n+1)//2−j
这里需要注意的是,假设A、B的长度满足m > n + 1,且当i=m时, j必须取负值以均衡左右两个部分的尺度相同。所以在以下部分,不妨假设A的长度m <= B的长度n.
-
如果A[i-1]存在的话, A[i-1] <= B[j]
-
如果B[j-1]存在的话, B[j-1] <= A[i]
class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
m, n = len(nums1), len(nums2)
if m > n:
nums1, nums2, m, n = nums2, nums1, n, m
imin, imax, half = 0, m, (m + n + 1) // 2
while imin <= imax:
i = (imin + imax) // 2
j = half - i
#print(i, j, nums1, nums2)
if i > 0 and j < n and nums1[i-1] > nums2[j]:
imax = i - 1
elif j > 0 and i < m and nums2[j-1] > nums1[i]:
imin = i + 1
else:
if (m + n) % 2 == 1:
if i == 0:
return nums2[(m + n) // 2]
if j == 0:
return nums1[(m + n) // 2]
return max(nums1[i-1], nums2[j-1])
if m == 0:
return (nums2[(m + n) // 2] + nums2[(m + n) // 2 - 1]) / 2
if i == m:
right = nums2[j]
if j == 0:
left = nums1[i-1]
else:
left = max(nums1[i-1], nums2[j-1])
elif i == 0:
left = nums2[j-1]
if j == n:
right = nums1[i]
else:
right = min(nums1[i], nums2[j])
else:
left = max(nums1[i-1], nums2[j-1])
right = min(nums1[i], nums2[j])
return (left + right) / 2
调了好久的代码终于通过了,但是现在觉得写的还是比较啰嗦,很多逻辑不清楚。需要加强数组方面的逻辑了。
本文介绍了一种求解两个有序数组中位数的方法,利用中位数特性将数组划分成两个长度相等的部分,通过迭代查找实现O(log(m+n))的时间复杂度。

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



