给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
算法的时间复杂度应该为 O(log (m+n)) 。
示例 1:
输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
解释:合并数组 = [1,2,3] ,中位数 2
示例 2:
输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5
思路: 有序序列寻找k大值,二分
class Solution:def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:"""可以理解为是寻找第k大的数,当总个数是奇数时中位数位置是第n//2+1,偶数时中位数是(n//2+n//2+1)//2要实现log时间复杂度,考虑使用二分查找,每次排除不是中位数的一部分要找到第 k (k>1) 小的元素,那么就取 pivot1 = nums1[k/2-1] 和 pivot2 = nums2[k/2-1] 进行比较"""def getKthelem(k):# 两个数组都从0开始向后索引idx1,idx2=0,0while True:# 边界条件if idx1==m: # 第一个数组遍历完毕return nums2[idx2+k-1] # 直接返回第二个数组当前的k位置if idx2==n: # 第二个数组遍历完毕return nums1[idx1+k-1] # 直接返回第一个数组当前的k位置if k==1: # k变为1 说明已经找到第个数,取两个数组中的当前位置较小值return min(nums1[idx1],nums2[idx2])# 一般情况newIdx1=min(idx1+k//2-1,m-1) # 每次往后走k//2-1,注意和边界比较newIdx2=min(idx2+k//2-1,n-1)pivot1,pivot2=nums1[newIdx1],nums2[newIdx2]if pivot1<=pivot2: # pivot1和左边的数不满足条件,跳过k-=newIdx1-idx1+1 # k=k-k//2idx1=newIdx1+1else:k-=newIdx2-idx2+1 # k=k-k//2idx2=newIdx2+1m,n=len(nums1),len(nums2)total=m+nif total%2:return getKthelem((total+1)//2)else:return (getKthelem(total//2)+getKthelem(total//2+1))/2
