Bootstrap

算法随笔_41: 寻找两个正序数组的中位数_方法1

上一篇:算法随笔_40: 爬楼梯-CSDN博客

=====

题目描述如下:

给定两个大小分别为 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

 

 

 

 

 

 

 

 

;