问题描述:
给定两个大小为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
问题分析:
今天下午,zhongkeyuan面试题目。
方法1:
(1)先把两个数组合并,然后排序,直接求出结果。
(2)时间复杂度可以理解为: O((n+m)log(n+m))
或者 O(nlogn)
也行,都是一个数量级。
(3)很显然,没有满足题目要求。
方法2:切割法 - 参考官方解答进行梳理
(1) 为了方便,nums1
和nums2
用A
,B
代替。分别从A
、B
中找一个位置i
、j
,把两个数组分别开为两部分,如下:
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]
根据中位数的性质,很容易得到两个条件:
1、
2、
或
进一步可以得出:
(2) 如何确定i
,j
?,接着上面推导,可以得出下面两个条件。
1、 或者,
如果 n>=m
,此时,
,
,(始终保持n
大,这样为了是j
的非负性)
2、
这一过程,就可以通过二分法来查找来确定 i
的值了。
(3) 最后就根据n+m
的奇偶性,返回中位数,即可。时间复杂度 O(log min(n,m))
Python3实现:
# 方法 1
# 时间复杂度 O(nlogn)
# 排序法
class Solution:
def findMedianSortedArrays(self, nums1, nums2):
nums = sorted(nums1 + nums2) # 合并排序
if len(nums) % 2 == 0:
return (nums[len(nums) // 2] + nums[len(nums) // 2 - 1]) / 2
else:
return nums[len(nums) // 2]
if __name__ == '__main__':
nums1, nums2 = [1, 3], [3, 4]
solu = Solution()
print(solu.findMedianSortedArrays(nums1, nums2))
# 方法 2
class Solution:
def findMedianSortedArrays(self, nums1, nums2):
m, n = len(nums1), len(nums2)
if m > n:
nums1, nums2, m, n = nums2, nums1, n, m # 保持 n 始终大于 m
if n == 0:
return None
imin, imax, half_len = 0, m, int((m + n + 1) / 2)
while imin <= imax:
i = int((imin + imax) / 2)
j = half_len - i
# 确定 i j 两个值
if i < m and nums2[j - 1] > nums1[i]: # 现在说名 i 太小,应该增加
imin = i + 1
elif i > 0 and nums1[i - 1] > nums2[j]: # 现在说名 i 太大,应该减小
imax = i - 1
else:
# i 的值已经确定,现在找中间值
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 (m + n) % 2 == 1: # 奇数的情况下
return max_of_left
if i == m: # 确定右边界情况
min_of_right = nums2[j]
elif j == n:
min_of_right = nums1[i]
else:
min_of_right = min(nums1[i], nums2[j])
return (max_of_left + min_of_right) / 2.0
if __name__ == '__main__':
nums1, nums2 = [1, 3], [3, 4]
solu = Solution()
print(solu.findMedianSortedArrays(nums1, nums2))
声明: 总结学习,有问题或不妥之处,可以批评指正哦。
题目链接:leetcode-cn.com/problems/median-of-two-sorted-arrays/
参考链接:leetcode.com/problems/median-of-two-sorted-arrays/solution/