题目描述
给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的中位数。
原题地址:https://leetcode-cn.com/problems/median-of-two-sorted-arrays/
测试用例
- 示例 1
输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
解释:合并数组 = [1,2,3] ,中位数 2
- 示例 2
输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5
- 示例 3
输入:nums1 = [0,0], nums2 = [0,0]
输出:0.00000
- 示例 4
输入:nums1 = [], nums2 = [1]
输出:1.00000
- 示例 5
输入:nums1 = [2], nums2 = []
输出:2.00000
解题代码和思路
- 合并数组求中位数
class Solution(object):
def findMedianSortedArrays(self,nums1, nums2):
m = len(nums1)
n = len(nums2)
if m == 0 and n == 0:
raise("nums1 and nums2 size is 0")
#这里将数组的个数是偶数(中间两个数的平均值)
# 和奇数(中间数)的情况进行合并
left = (m+n+1) // 2 - 1
right = (m+n+2) // 2 - 1
#判断两个数组中是否有空的数组
if m == 0:
return (nums2[left]+nums2[right]) / 2
if n == 0:
return (nums1[left]+nums1[right]) / 2
#用来保存排序后的数组
sort_nums = [0] * (m+n)
#记录两个数组下标的移动位置
nums1_index = 0
nums2_index = 0
for i in range(m+n):
if nums1[nums1_index] <= nums2[nums2_index]:
sort_nums[i] = nums1[nums1_index]
nums1_index += 1
else:
sort_nums[i] = nums2[nums2_index]
nums2_index += 1
if nums1_index == m:
sort_nums[i+1:] = nums2[nums2_index:]
break
if nums2_index == n:
sort_nums[i+1:] = nums1[nums1_index:]
break
#计算中位数
return (sort_nums[left]+sort_nums[right]) / 2
- 移动下标找中位数的位置
class Solution(object):
def findMedianSortedArrays(self,nums1,nums2):
m = len(nums1)
n = len(nums2)
if m == 0 and n == 0:
raise("nums1 and nums2 size is 0")
#用来记录左边和右边的数值
left = 0
right = 0
#用来记录数组下标的位置
left_index = 0
right_index = 0
#遍历数组到中位数的位置
for i in range((m+n)//2+1):
left = right
if left_index < m and (right_index >= n or nums1[left_index] < nums2[right_index]):
right = nums1[left_index]
left_index += 1
else:
right = nums2[right_index]
right_index += 1
if (m+n) % 2 == 0:
return (left+right) / 2
else:
return right
- 利用寻找k最小值法来找中位数
class Solution(object):
def getKmin(self,begin1,end1,begin2,end2,k):
"""获取两个已经排好序的数组中第k个最小值
:param begin1:
:param end1:
:param begin2:
:param end2:
:param k:
:return:
"""
len1 = end1 - begin1 + 1
len2 = end2 - begin2 + 1
if len1 == 0:
return self._nums2[begin2+k-1]
if len2 == 0:
return self._nums1[begin1+k-1]
if k == 1:
return min(self._nums1[begin1],self._nums2[begin2])
i = begin1 + min(k // 2,len1) - 1
j = begin2 + min(k // 2,len2) - 1
if self._nums1[i] > self._nums2[j]:
return self.getKmin(begin1,end1,j+1,end2,k-(j-begin2+1))
else:
return self.getKmin(i+1,end1,begin2,end2,k-(i-begin1+1))
def findMedianSortedArrays(self,nums1,nums2):
self._nums1 = nums1
self._nums2 = nums2
self._m = len(nums1)
self._n = len(nums2)
if self._m == 0 and self._n == 0:
raise ("nums1 and nums2 size is 0")
left = (self._m + self._n + 1) // 2
right = (self._m + self._n + 2) // 2
return (self.getKmin(0,self._m-1,0,self._n-1,left)+self.getKmin(0,self._m-1,0,self._n-1,right)) / 2
- 分割切片算法
class Solution(object):
def findMedianSortedArrays(self,nums1,nums2):
m = len(nums1)
n = len(nums2)
if m == 0 and n == 0:
raise ("nums1 and nums2 size is 0")
if m > n:
return self.findMedianSortedArrays(nums2,nums1)
i_min = 0
i_max = m
while i_min <= i_max:
i = (i_min+i_max) // 2
j = (m+n+1) // 2 - i
if i != 0 and j != n and nums1[i-1] > nums2[j]:
i_max = i - 1
elif j != 0 and i != m and nums2[j-1] > nums1[i]:
i_min = i + 1
else:
if i == 0:
max_left = nums2[j-1]
elif j == 0:
max_left = nums1[i-1]
else:
max_left = max(nums1[i-1],nums2[j-1])
if (m+n) % 2 == 1:
return max_left
if i == m:
max_right = nums2[j]
elif j == n:
max_right = nums1[i]
else:
max_right = min(nums1[i],nums2[j])
return (max_left+max_right) / 2
具体详细的解答参考Leetcode题解