寻找两个有序数组的中位数
题目描述:
给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。
请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。
你可以假设 nums1 和 nums2 不会同时为空。
示例 1:
nums1 = [1, 3]
nums2 = [2]
则中位数是 2.0
示例 2:
nums1 = [1, 2]
nums2 = [3, 4]
则中位数是 (2 + 3)/2 = 2.5
解题思路:
整体思路类似于在一个无序数组内找需要的第k个数。
我们通过两个数组各自的中位数,将中位数的左右两侧分为四个部分,分别为A1
、A2
、B1
、B2
。(有A1
<A2
,B1
<B2
)现在我们来找出他们中第k
小的数。如果A
的中位数比B
的中位数大,那么B1
中的数比A2
和B2
中的都小,且小于部分A1
中的数。此时,如果 ,那么第k
个数就不可能在B1
,因为比B1
的数小的数最多只有B1
加上部分的A1
,也就是 ,矛盾。
同时,我们还知道了A2
中的数比A1
和B1
的大,且比部分B2
的大,此时,如果 ,那么第k
个数就不可能在A2
中,因为A2
中的数至少比A1
加B1
中的数大,也就是 ,矛盾。同理可以推理出另外两种情况。之后就可以通过递归的方式不断缩小数组的范围,直到找到结果。
Python源码:
from typing import List
class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
length1 = len(nums1)
length2 = len(nums2)
k = (length1 + length2) // 2
if (length1 + length2) % 2 == 0:
return (self.findK(nums1, nums2, k) + self.findK(nums1, nums2, k - 1)) / 2.0
else:
return self.findK(nums1, nums2, k)
def findK(self, num1, num2, k):
# Recursive ends here
if not num1:
return num2[k]
if not num2:
return num1[k]
if k == 0:
return min(num1[0], num2[0])
length1 = len(num1)
length2 = len(num2)
if num1[length1 // 2] > num2[length2 // 2]:
if k > length1 // 2 + length2 // 2:
return self.findK(num1, num2[length2 // 2 + 1:], k - length2 // 2 - 1)
else:
return self.findK(num1[:length1 // 2], num2, k)
else:
if k > length1 // 2 + length2 // 2:
return self.findK(num1[length1 // 2 + 1:], num2, k - length1 // 2 - 1)
else:
return self.findK(num1, num2[:length2 // 2], k)
欢迎关注我的github:https://github.com/UESTCYangHR