算法6-----查找兩個有序數組合並之后的中位數


1、題目:

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

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

 

2、法1:歸並排序

nums1的最后一個數和nums2的最后一個數對比。如果nums1的值大,將該值存入新的結果數組中,並將nums1最后一個數刪除,則nums1的倒數第二個數就成為了最后一個。這樣只要一直將nums1和nums2最后一個數對比。

class Solution:
    def findMedianSortedArrays(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: float
        """
        nums1.reverse()
        nums2.reverse()
        temp=[]
        while nums1 and nums2:
            if nums1[-1]<=nums2[-1]:
                temp.append(nums1[-1])
                nums1.pop()
            else:
                temp.append(nums2[-1])
                nums2.pop()
        if not nums1 and nums2:
            nums2.reverse()
            temp.extend(nums2)
        elif not nums2 and nums1:
            nums1.reverse()
            temp.extend(nums1) 
        if len(temp)%2==1:
            return temp[len(temp)//2]
        else:
            return (temp[len(temp)//2]+temp[len(temp)//2-1])/2

法2:分治法:

分:由於兩個數組合並之后的中位數,比較nums1和nums2的中位數a,b,若a<b,則合並數組的中位數在a的右邊,b的左邊。若a>b,則合並數組的中位數在a的左邊,b的右邊。

  假設:

  nums1中位數  i=len(A)//2

  nums2中位數  j=k-i 【k=(len(A)+len(B))//2】

治:最小的子問題有三種:

  一、nums1空,nums2只有一個值【返回nums2的值,因為合並的中位數也是該值】

  二、nums1只有一個值,nums2空【返回nums1的值,因為合並的中位數也是該值】

  三、nums1和nums2都只有一個值a和b【此時應該返回兩個值a,b。繼續分nums1和nums2,發現一種情況分為空和非空的可以返回一個值,另一種情況出現無法索引到數組中1的值。】

    如nums1=【1】,nums2=【2】

    m=len(nums1)+len(nums2)=2,則應返回k=m//2-1=0和k=m//2=1的值。

    當k=0時,i=len(nums1)/2=0, j=k-i=0,   【i,j作為兩個數組的中位數索引】  nums1[i]=1, nums[j]=2,比較兩者大小,1<2,取1右邊的數(包括1)為【1】,取2左邊的數(不包括2)為空【】,則【1】和【】返回1。----------------這種情況只會返回nums1和nums2中較小的數。

    當k=1時,i=len(nums1)/2=0,j=k-i=1,發現沒有這個索引,所以這種情況發生時無法返回數。這是需要強制給它返回一個值,即返回nums1和nums2中較大的值

 

    故第三種情況:if k==1 and len(nums1)==1 and len(nums2)==1:

              return max(nums1[0],nums[0])

def findMid(nums1,nums2):
    l=len(nums1)+len(nums2)
    return findKthMid(nums1,nums2,l//2) if l%2==1 else (findKthMid(nums1,nums2,l//2-1)+findKthMid(nums1,nums2,l//2))/2

def findKthMid(nums1,nums2,k):
    if not nums1 and nums2:
        return nums2[k]
    if not nums2 and nums1:
        return nums1[k]
    if k==1 and len(nums1)==1 and len(nums2)==1:
        return max(nums1[0],nums2[0])
    i=len(nums1)//2
    j=k-i
    if nums1[i]>nums2[j]:
        return findKthMid(nums1[:i],nums2[j:],i)
    else:
        return findKthMid(nums1[i:],nums2[:j],j)

 


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com