题目:给定长度为m和n的两个有序数组nums1和nums2,找出两个有序数组的中位数,要求时间复杂度为O(log(m+n))
法:hard题,看了好几次都没太懂原理....参照leetcode all in one的题解,勉勉强强写出个python版本。题解地址:http://www.cnblogs.com/grandyang/p/4465932.html
比较核心的就是 变相的二分,靠比较nums1的中位数与nums2的中位数,来缩小边界。举例来说,设两个数组的中位数分别为val1与val2,如果val1小于val2,说明val1之前的元素都小于val1,去除这些元素,要找的结果只能存在nums1中val1往后的元素与nums2中,那么就修改nums1的查找起点,整体查找长度就变成了1/2*len(nums1)+len(nums2)
有几点需要注意的是:
1)这里我们不对长度区分奇偶,举例说明,设nums1与nums2的长度分别为m与n,假设m=1,n=2,总体长度为奇数,那么要找的中位数为第2个,left=(m+n+1)//2=2,right=(m+n+2)//2=2,正好都满足;同样的假设m=2,n=2,总体长度为偶数,那么要找的中位数为第2,第3个,left=(m+n+1)//2=2,right=(m+n+2)//2=3,正好也都满足。
2)这里找的第k个数,正好与下标差1
3)要时刻注意判断下标是否超过查找的数组长度
def findMedianSortedArrays(self, nums1, nums2):
"""
:type nums1: List[int]
:type nums2: List[int]
:rtype: float
"""
m,n=len(nums1),len(nums2)
left,right=(m+n+1)//2,(m+n+2)//2
return float((self.helper(nums1,0,nums2,0,left)+self.helper(nums1,0,nums2,0,right)))/2.0
def helper(self,nums1,i,nums2,j,k):
if i>=len(nums1):return nums2[j+k-1]
if j>=len(nums2):return nums1[i+k-1]
if k==1:return min(nums1[i],nums2[j])
val1=nums1[i+k//2-1] if i+k//2-1 <len(nums1) else 2**31
val2=nums2[j+k//2-1] if j+k//2-1 <len(nums2) else 2**31
if val1<val2:
return self.helper(nums1,i+k//2,nums2,j,k-k//2)
else:
return self.helper(nums1,i,nums2,j+k//2,k-k//2)