4.Median of Two Sorted Arrays
本次是LC第4题,要求找两个有序数组的中位数
题干:
There are two sorted arrays nums1 and nums2 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)).
You may assume nums1 and nums2 cannot be both empty.
解释:
题干中给了三个重要的信息: 1,有序 2,中位数 3,复杂度log(m+n)
思考:
因为是有序,所以肯定要用二分法,log(m+n)也验证了这一点 然后要找中位数,最直接的想法肯定是用直接拼一起sort,但是复杂度是m+n(log (m+n))了,也不行。 再仔细想想,中位数还可以用平衡二叉树的思路,也就是两个堆来做,但是由于不用动态保持,所以两个堆的意义也不是很大。
答案:
长度为m+n的数组的中位数Kth,等于长度为m+n-K/2的数组的第K/2个数
这句话是从评论区高赞老哥的思路中总结出来的,的确是很妙,二分法的核心就是淘汰,每次淘汰一部分从而避免运算,第K大的数一定不会出现在第K/2大的数之前。淘汰的具体办法是使用两个pointer来标志起始位置。递归的终点是起始位置大于数组长度了。 根据这个思路写出以下python代码:
class Solution:
def findMedianSortedArrays(self, nums1, nums2) :
m = len(nums1)
n = len(nums2)
left =(m+n+1)//2
right = (m+n+2)//2
return (helper(nums1,0,nums2,0,left)+helper(nums1,0,nums2,0,right))/2.0
def helper(self,nums1,i,nums2,j,k):
#首先是确认递归终点:当i,j的长度大于数组的长度时,直接返回另外一个数组中相应位置即可
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])
midVal1 = nums1[i+k//2-1] if i+k//2-1 < len(nums1) else 10000000000
midVal2 = nums2[j+k//2-1] if j+k//2-1 < len(nums2) else 10000000000
if midVal1<midVal2:
return helper(nums1,i+k//2,nums2,j,k-k//2)
else :
return helper(nums2,i,nums2, j+k//2,k-k//2)
时间排名是66%,感觉还有优化空间,于是又参看了一下别人的python,发现如果都把短的数据放前面的话效果会更好,这是别人的代码,时间是73%
class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
def findKthElement(arr1,arr2,k):
len1,len2 = len(arr1),len(arr2)
if len1 > len2:
return findKthElement(arr2,arr1,k)
if not arr1:
return arr2[k-1]
if k == 1:
return min(arr1[0],arr2[0])
i,j = min(k//2,len1)-1,min(k//2,len2)-1
if arr1[i] > arr2[j]:
return findKthElement(arr1,arr2[j+1:],k-j-1)
else:
return findKthElement(arr1[i+1:],arr2,k-i-1)
l1,l2 = len(nums1),len(nums2)
left,right = (l1+l2+1)//2,(l1+l2+2)//2
return (findKthElement(nums1,nums2,left)+findKthElement(nums1,nums2,right))/2
这个题差不多也就这样了。