=====
题目描述如下:
给定两个大小分别为 m
和 n
的正序(从小到大)数组 nums1
和 nums2
。请你找出并返回这两个正序数组的 中位数 。
示例 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
=====
算法思路:
解法1:
题目要求找到这两个正序数组的中位数,我们可以考虑把这两个数组进行合并,合并之后,如果数组总长度为奇数,那么正中间的那个数就是中位数。如果是偶数,那么最中间的两个数值的平均数就是中位数。
我们使用两个指针p1,p2来做合并的动作。这两个指针初始时分别指向两个数组的起始位置,然后比较nums1[p1],nums2[p2]的大小,我们把较小值存入结果数组res中,然后右移较小值的指针,然后再次比较。每次比较都把较小值存入结果数组res,然后右移较小值的指针。循环交替,直到合并完成。
时间复杂度和空间复杂度都是O(n) 。
下面是代码实现:
class Solution(object):
def findMedianSortedArrays(self, nums1, nums2):
"""
:type nums1: List[int]
:type nums2: List[int]
:rtype: float
"""
res=[]
n1_len=len(nums1)
n2_len=len(nums2)
p1=0
p2=0
while p1 < n1_len or p2 < n2_len:
if p1>=n1_len:
res.append(nums2[p2])
p2+=1
elif p2>=n2_len:
res.append(nums1[p1])
p1+=1
elif nums1[p1]<nums2[p2]:
res.append(nums1[p1])
p1+=1
else:
res.append(nums2[p2])
p2+=1
res_len=len(res)
if res_len%2==0:
return (res[res_len//2-1]+res[res_len//2])/2.0
else:
return res[res_len//2]
*****
解法2:
根据上面的算法,我们发现其实不用合并数组,也能得出答案。
因为两个数组的长度是已知的,因此合并后的数组res的长度res_len可以计算得出。最终中位数的位置也可以计算得出。如果res_len是偶数,需要算出两个下标,res_len//2-1和res_len//2,如果res_len是奇数,需要算出下标,res_len//2。
和上面的解法1类似,在解法2里,我们无需res数组,只定义了几个变量来存储中间的状态,并且到达中位数的位置即可退出循环。
时间复杂度为O(n) 。由于省略了res数组,且仅使用了常量空间,所以空间复杂度为O(1) 。
下面是代码实现:
class Solution(object):
def findMedianSortedArrays(self, nums1, nums2):
"""
:type nums1: List[int]
:type nums2: List[int]
:rtype: float
"""
n1_len=len(nums1)
n2_len=len(nums2)
p1=0
p2=0
res_len=n1_len+n2_len
pre=0
cur=0
for i in range(res_len//2+1):
pre=cur
if p1<n1_len and (p2>=n2_len or nums1[p1]<nums2[p2]):
cur=nums1[p1]
p1+=1
else:
cur=nums2[p2]
p2+=1
if res_len%2==0:
return (pre+cur)/2.0
else:
return cur