004.尋找兩個有序數組的中位數

There are two sorted arrays nums1 and nums2 of size m and n respectively.算法

Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).數組

Example 1:.net

nums1 = [1, 3] nums2 = [2]code

The median is 2.0get

Example 2:同步

nums1 = [1, 2] nums2 = [3, 4]博客

The median is (2 + 3)/2 = 2.5it

給定兩個大小爲 m 和 n 的有序數組 nums1 和 nums2 。io

請找出這兩個有序數組的中位數。要求算法的時間複雜度爲 O(log (m+n)) 。class

1.本身的想法是 一共m + n 個,咱們能夠新建一個List 而後每把最小的數放進去,代碼以下:

class Solution:
    def findMedianSortedArrays(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: float
        """
        leng = len(nums1) + len(nums2)
        tmpLen = leng//2 + 1
        newList = [0]*tmpLen
        i = 0
        j = 0
        for k in range(tmpLen):
            if i == len(nums1):
                newList[k] = nums2[j]
                j += 1
            elif j == len(nums2):
                newList[k] = nums1[i]
                i += 1
            else:
                if nums1[i] < nums2[j]:
                    newList[k] = nums1[i]
                    i += 1
                else:
                    newList[k] = nums2[j]
                    j += 1
        if leng %2 == 0:
            return (newList[tmpLen - 2] + newList[tmpLen - 1])/2
        else:
            return newList[tmpLen - 1]

2.相似與折半查找的思路,

因爲題目要求的時間複雜度是(log(m+n)),若是咱們直接把兩個數組整合一塊兒,那麼時間複雜度確定超過(log(m+n))。因此整理確定是不行的。那麼還有什麼方法嗎?答案是確定的。

     首先咱們要先了解中位數的概念,中位數就是有序數組的中間那個數。那麼若是咱們將比中位數小的數和比中位數大的數去掉一樣的個數,中位數的值也不會變化(數組的個數爲偶數的時候另外討論,由於那時候中位數是中間兩個數的平均值,因此中位數旁邊兩個數不能去掉)

     因此咱們不妨試着將數組長度不斷縮短。這裏不妨提出一個引理。假設有兩個有序數組am,bn,他們整合後的有序數組爲cn+m。他們的中位數分別是Am/2,Bn/2,C(m+n)/2。若是Am/2 < Bn/2,則 A0…m/2 <= C(m+n)/2 <= Bn/2…n 。

     引理證實:

           假設 Am/2 > C(m+n)/2 ,那麼 Bn/2  > C(m+n)/2,因此在數組Am裏有大於m/2個數大於C(m+n)/2,在數組Bn裏也有n/2個數大於C(m+n)/2

           也就是說在Cn+m裏有(m+n)/2個數大於C(m+n)/2,此時就C(m+n)/2再也不是數組Cn+m的中位數。

           因此A0…m/2 <= C(m+n)/2。

           同理可得C(m+n)/2 <= Cn/2…n 。

    根據上述引理,咱們不妨設m>n,那麼咱們根據判斷兩個數組的中位數大小,每一個數組每次減小n/2長度,直到n爲1。如此,咱們經過減小log(n)次能夠獲得答案。這種方法的時間複雜度是(log(min(m,n)))。

class Solution:
    def getMedian(self,nums):
        size = len(nums)
        if size == 0:
            return [0,0]
        if size % 2 == 1:
            return [nums[size//2],size//2]
        else:
            return [(nums[size//2 - 1] + nums[size//2])/2,size//2]
    
    def findMedianSortedArrays(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: float
        """
        size1 = len(nums1) # ig longer
        size2 = len(nums2)
        if size1 < size2:
            return self.findMedianSortedArrays(nums2,nums1)
        m1 = self.getMedian(nums1)
        m2 = self.getMedian(nums2)
        if size2 == 0:
            return m1[0]
        if size2 == 1:
            if size1 == 1:
                return (m1[0] + m2[0])/2
            if size1 % 2 == 0:
                if nums2[0] < nums1[size1//2 - 1]:
                    return nums1[size1//2 -1]
                if nums2[0] > nums1[size1//2]:
                    return nums1[size1//2]
                else:
                    return nums2[0]
            else:
                if nums2[0] < nums1[size1//2 - 1]:
                    return (nums1[size1//2 - 1] + nums1[size1//2])/2
                if nums2[0] > nums1[size1//2 + 1]:
                    return (nums1[size1//2 + 1] + nums1[size1//2])/2
                else:
                    return (nums2[0] + nums1[size1//2])/2
        if size1 % 2 == 0:
            if size2 % 2 == 0:
                if nums1[size1//2 - 1] > nums2[size2//2 - 1] and nums2[size2//2] > nums1[size1//2]:
                    return m1[0]
                if nums1[size1//2 - 1] < nums2[size2//2 - 1] and nums2[size2//2] < nums1[size1//2]:
                    return m2[0]
        if m1[0] < m2[0]:
            return self.findMedianSortedArrays(nums1[m2[1]:],nums2[:size2 - m2[1]])
        if m1[0] > m2[0]:
            return self.findMedianSortedArrays(nums1[:size1 - m2[1]],nums2[m2[1]:])
        else:
            return m1[0]

 

本文同步分享在 博客「SoWhat1412」(CSDN)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索