There are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
Note:
median: 中位数
1. 对于奇数长度的数组,中位数是即是排序后的中间数。
2. 对于偶数长度的数组,中位数是排序后数组的中间两个数的平均值。
Solution:
这道题直观的解法是归并排序(merge sort),不过那样的话时间复杂度是O((m+n)log(m+n)),不符合题目所要求的O(log(m+n))。
通常O(log(n))的时间复杂度我们会联想到二分查找(binary search),分治法(divide and conquer)。
可以把求中位数转换为求两个排序数组的第k位数。k = (lenA + lenB)/2 or (lenA + lenB)/2 + 1
我们将数组A中的第k/2位数与数组B中的k - k/2进行比较(如果k/2大于数组A的长度的话,则将A最后一位数与B中第k - lenB位进行比较)。
综上,即取temp = min(k/2, lenA), 比较A[temp-1] 与 B[k-temp-1]的大小(这里A为长度较短的数组):
如果A[temp-1]小于B[k-temp-1], 则在A[0:temp]中必然不存在这第k个数,省去,接下来则求在A[temp:]与B中的第k-temp个数。反之,在B[0:k-temp]中必然不存在这第k个数。
举例:
A = [1, 3, 7, 8]
B = [2, 5, 10. 18, 25, 50]
求A, B两数组的第5位数。
temp = 2
A中第2位数小于B中第3位数,这个则表明在A中的前两位数均小于我们所要找的第5位数(有点绕~lol)。所以需要在A数组的剩余部分与B数组中继续寻找第(5-2)位数,这样就成功应用了divide and conquer。
具体代码如下,注意考虑边界条件。(A B 数组长度比较,某一数组为空.etc)
class Solution:
# @return a float
def findMedianSortedArrays(self, A, B):
lenA = len(A)
lenB = len(B)
if (lenA + lenB) % 2 == 1:
return self.findKthElement(A, B, (lenA+lenB)/2 + 1)
else:
return (self.findKthElement(A, B, (lenA+lenB)/2 + 1) + self.findKthElement(A, B, (lenA+lenB)/2))*0.5
def findKthElement(self, A, B, k):
lenA = len(A)
lenB = len(B)
if lenA > lenB:
return self.findKthElement(B, A, k)
if lenA == 0:
return B[k-1]
if k == 1:
return min(A[0], B[0])
temp = min(k/2, lenA)
if A[temp-1] < B[k-temp-1]:
return self.findKthElement(A[temp:], B, k-temp)
else:
return self.findKthElement(A, B[k-temp:], temp)