给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。你可以假设 nums1 和 nums2 不会同时为空。
方法一:利用sort排序
class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
# nums1.sort()#函数没有返回值
# nums2.sort()
while nums2 != []:
nums1.append(nums2.pop())
nums1.sort()
if (len(nums1)%2) == 0:
c1 = (nums1[len(nums1)//2] + nums1[(len(nums1)//2)-1])/2
else:
c1 = nums1[len(nums1)//2]
return c1
此方法利用排序直接寻找中位数,不解释。可以过,复杂度不符合要求
方法二:二分法
class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
if len(nums1) > len(nums2):
nums1,nums2 = nums2,nums1
m = len(nums1)
n = len(nums2)
left = 0
right = m
while left <= right:
i = (left + right) >> 1
j = ((m + n + 1)>>1)-i
nums1_left_max = float('-inf') if i == 0 else nums1[i-1]
nums1_right_min = float('inf') if i == m else nums1[i]
nums2_left_max = float('-inf') if j == 0 else nums2[j-1]
nums2_right_min = float('inf') if j == n else nums2[j]
if nums1_left_max <= nums2_right_min and nums1_right_min >= nums2_left_max:
if m+n & 1:
return max(nums1_left_max,nums2_left_max)
else:
return (max(nums1_left_max,nums2_left_max)+min(nums1_right_min,nums2_right_min))/2
elif nums1_left_max > nums2_right_min:
right = i-1
else:
left = i+1
二分法寻找中位数,复杂度也符合要求。
每个list分成左右两个部分
若两个list的元素个数之和为偶数,那么size左= size右
若两个list的元素个数之和为奇数,那么size左 = size右+1
list1左半部分的个数为i,list2左半部分的个数为j
且满足,i+j = (m+n+1)/ 2
然后在判断一下边界条件,因为有的时候一个list不需要分成两个部分,比如list1里的元素都小于list2的元素
方法三:双指针法
class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
if len(nums1) < len(nums2):
nums1,nums2 = nums2,nums1
m = len(nums1)
n = len(nums2)
s = m + n
p = 0
q = 0
if m < n:
nums1,nums2 = nums2,nums1
while p<m and q<n:
if p+q >=(s-1)//2:
x = nums1[p]
y = nums2[q]
if x < y and p+1<m and nums1[p+1]<y:
y = nums1[p+1]
if y<x and q+1<n and nums2[q+1] <x:
x = nums2[q+1]
if s&1:
return min(x,y)
else:
return (x+y) /2
elif nums1[p] > nums2[q]:
q+=1
else:
p+=1
while p+n <s//2:
p+=1
if s&1:
return nums1[p]
else:
return (nums1[p]+nums1[p-1])/2
索引从0开始,依次比较两个list里元素的值,小的list 索引+1,再比较,记录比较次数,直至次数到中位数的位置