题目
给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
算法的时间复杂度应该为 O(log (m+n)) 。
示例
输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
解释:合并数组 = [1,2,3] ,中位数 2
输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5
解法一
可以直接合并数组,同时在合并的过程中找到第(m+n+1)/2的数,如果是偶数数组,还需要找到下一个数。合并的过程和第88题类似。该时间复杂度为O(m+n),不符合题要求。
class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
p1=0
p2=0
x=0
cur=0
cur2=0
m=len(nums1)
n=len(nums2)
while p1<m or p2<n:
if p1==m:
cur=nums2[p2]
p2+=1
elif p2==n:
cur=nums1[p1]
p1+=1
elif nums1[p1]<nums2[p2]:
cur=nums1[p1]
p1+=1
else:
cur=nums2[p2]
p2+=1
x+=1
if (m+n)%2==1 and x==(m+n+1)/2:
return cur
break
if (m+n)%2==0 and x==(m+n)/2:
cur2=cur
if (m+n)%2==0 and x==(m+n)/2+1:
return (cur+cur2)/2
解法二
要达到O(log(M+N))的时间复杂度。需要使用二分查找的方法。
根据中位数的定义,当 m+n 是奇数时,中位数是两个有序数组中的第 (m+n)/2 个元素,当 m+n是偶数时,中位数是两个有序数组中的第 (m+n)/2个元素和第 (m+n)/2+1 个元素的平均值。因此,这道题可以转化成寻找两个有序数组中的第 k 小的数,其中 k 为 (m+n)/2 或 (m+n)/2+1。
从而使用二分法,可以比较 A[k/2−1] 和B[k/2−1] 之后,可以排除 k/2 个不可能是第 k 小的数,查找范围缩小了一半。当k变成1时,比较指针当前指向的两个数,小的即为第k小的数。
class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
def findindex(k):
index1=0
index2=0
while True:
if index1==m:
return nums2[index2+k-1]
if index2==n:
return nums1[index1+k-1]
if k==1:
return min(nums1[index1],nums2[index2])
newindex1=min(index1+k//2-1,m-1)
newindex2=min(index2+k//2-1,n-1)
if nums1[newindex1]<=nums2[newindex2]:
k-=newindex1-index1+1
index1=newindex1+1
if nums1[newindex1]>nums2[newindex2]:
k-=newindex2-index2+1
index2=newindex2+1
m=len(nums1)
n=len(nums2)
if (m+n)%2==0:
return (findindex((m+n)//2)+findindex((m+n)//2+1))/2
else:
return findindex((m+n+1)//2)