首先是找出两个正序数组并起来的topk,就自然可以求出中位数啦!
怎么求topk?
分三种情况:k <=短数组长度, 短数组长度<k<=长数组长度, k>=长数组长度
三种情况都可以简化数组,去除不可能成为topk的元素
目的是化为 “两个等长数组求上分位数”等价。也就是求出这两个等长数组的上分位数就相当于求出了topk。
这个目的就涉及了两个问题,一个是怎么化成这种形式,另一个就是怎么求两个等长数组的上分位数?
怎么化成这种形式:
1、k <=短数组长度
2、短数组长度<k<=长数组长度
3、k>=长数组长度
怎么求两个等长数组的上分位数?本质也是去掉不可能是上分位数的数字,去掉之后递归这两个数组,知道两个数组长度为1。但当单个数组长度是奇数,递归可能会提前结束。
1、当单个数组的长度是偶数
[1,2,3,4] [1,2]
--------------->
[1,2,3,4] [3,4]
2、当单个数组的长度是奇数
class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
import copy
# 首先是将中位数转为求top k
# 然后转化成等长数组求上分位数
def topK_num(array1, array2, k):
def lower_median(arr1, arr2):
if len(arr1) != len(arr2):
raise Exception("长度不等错误")
length = len(arr1)
# 递归终止条件,返回上中位数
if length == 1:
return min(arr1[0], arr2[0])
# 当数组长度为偶数
if length & 1 == 0:
# arr1和arr2的上分位数比较
median = int(length/2)
if arr1[median-1] == arr2[median-1]:
return arr1[median-1]
elif arr1[median-1] < arr2[median-1]:
temp = copy.deepcopy(arr1)
arr1 = arr2
arr2 = temp
if arr1[median-1] > arr2[median-1]:
lower_median_num = lower_median(arr1[:median],arr2[median:])
# 当数组长度为奇数
else:
if arr1[length//2] == arr2[length//2]:
return arr1[length//2]
elif arr1[length//2] < arr2[length//2]:
temp = copy.deepcopy(arr1)
arr1 = copy.deepcopy(arr2)
arr2 = temp
if arr1[length//2] > arr2[length//2]:
arr1 = arr1[:length//2]
arr2 = arr2[length//2:]
# 此时不等长,要判断删掉arr2的第一个元素
# 需要手动判断一下arr2的第一个元素与arr1的最后一位谁大
if arr2[0] > arr1[-1]:
return arr2[0]
else:
lower_median_num = lower_median(arr1,arr2[1:])
return lower_median_num
# 确保array1是较短的那个数组
length_arr1 = int(min(len(array1), len(array2)))
length_arr2 = int(max(len(array1), len(array2)))
if len(array1) > len(array2):
temp = copy.deepcopy(array1)
array1 = copy.deepcopy(array2)
array2 = temp
total_length = length_arr1 + length_arr2
if not length_arr1 and not length_arr2:
return None
elif not length_arr1:
if length_arr2 & 1 == 0:
median = int(length_arr2/2)
return (array2[median-1] + array2[median])/2
else:
return array2[length_arr2//2]
k = int(k)
# 分三种情况
if k <= length_arr1:
array1 = array1[:k]
array2 = array2[:k]
return lower_median(array1, array2)
elif k > length_arr1 and k <= length_arr2:
array2 = array2[k-length_arr1-1:k]
if array2[0] >= array1[-1]:
return array2[0]
else:
array2 = array2[1:]
return lower_median(array1, array2)
elif k > length_arr2:
array2 = array2[k-length_arr1-1:]
if array1[0] >= array2[-1]:
return array1[0]
elif array2[0] >= array1[-1]:
return array2[0]
else:
array1 = array1[1:]
array2 = array2[1:]
return lower_median(array1, array2)
# 开始求中位数,就是判断取top几
if (len(nums1) + len(nums2)) & 1 != 0:
return topK_num(nums1, nums2, int((len(nums1) + len(nums2))//2+1))
else:
lower = topK_num(nums1, nums2, int((len(nums1) + len(nums2))/2))
higher = topK_num(nums1, nums2, int((len(nums1) + len(nums2))/2+1))
return (lower + higher) / 2