@[LeetCode 4 --寻找两个有序数组的中位数]
寻找两个有序数组的中位数
题目
题目分析
(和leetcode官方题解的思路一样,只是加了一些自己的理解)
- 首先要理解中位数的含义:中位数将一个集合分成两个大小相等的部分,并且中位数总是大于第一个子集的元素,小于第二个子集的元素。
- 在这道题中有两个有序数组,他要求时间复杂度为 O(log(m + n)),有两种方法,第一种是将两个数组合并起来后用归并排序或者二分法排序找到中位数,另一种方法是递归法,在这里我们详细介绍递归法:
left_part | right_part |
---|---|
A[0], A[1],…, A[ i-1 ] | A[ i ], A[ i+1 ],…,A[ m-1 ] |
B[0], B[1],…, B[ j-1 ] | B[ j ], B[ j+1 ],…,B[ n-1 ] |
- 根据中位数的定义,上面的表格应该满足:
- len(left_part) = len(right_part)
- max(left_part) ≤ min(right_part)
- left_part 和 right_part 并不需要排序只是把他的放在一起,这道题的关键就是求出 i 和 j 下标,根据下标找到对应的值然后求出中位数
- i 和 j 主要出现3种情况 :
B[ j -1 ] <= A [ i ] 且 A [ i -1 ] <= B[ j ] 意味着找到了目标对象i
B [j -1 ] > A[ i ] : 那就增大i, 减少j
A [ i -1 ] >B [ j ]: 那就减少i, 增大j
- 求出指定的i,j就可以得到中位数
代码
#递归法
class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
n1 = len(nums1)
n2 = len(nums2)
if n1>n2:
n1, n2, nums1, nums2 = n2, n1, nums2, nums1
size = n1 + n2
imin, imax, half_len = 0, n1, (n1+n2+1)/2
while imin<=imax:
i = (imin+imax)/2
j = half_len/2
if i < n1 and nums2[j-1] > nums1[i]:
imin = i+1
elif i > 0 and nums1[i-1] > nums2[j]:
imax = i-1
else:
if i == 0: max_of_left = nums2[j-1]
elif j==0: max_of_left = nums1[i-1]
else:
max_of_left = max(nums1[i-1], nums2[j-1])
if(n1+n2) % 2 == 1:
return max_of_left
if i == n1: min_of_right = nums2[j]
elif j == n2: min_of_right = nums1[i]
else:
min_of_right = min(nums1[i], nums2[j])
return ((max_of_left+min_of_right)/2)
下面是最直接求中位数的方法
class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
n = nums1 +nums2
n = sorted(n, reverse=False)
m = len(n)
if m %2 == 0:
a = m/2
tem=n1[a-1]+n1[a]
return tem/2
else:
return n1[m//2]