Leetcode第四題:尋找兩個正序數組的中位數

題目:

給定兩個大小爲 m 和 n 的正序(從小到大)數組 nums1 和 nums2。

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

你可以假設 nums1 和 nums2 不會同時爲空。

 

示例 1:

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

則中位數是 2.0
示例 2:

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

則中位數是 (2 + 3)/2 = 2.5

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。

個人思路:

沒思路

官方答案推薦:

①求中位數可視爲求第k小的數。計算出中位數所在位置k,每次取兩數組k//2位置的數來比較,小的一方則爲中位數前的部分數據,移出數組,更新k,繼續循環比較。原理:A[k/2] 最多是第 k-1 小的數,所以可排除之前的數。

②使用分割法分割兩個數組爲四部分,使max(ALeftMax,BLeftMax)和min(ARightMin,BRightMin)之間的數爲中位數。保證左右分割後長度相同,ALeftMax<BRightMin,BLeftMax<ARightMin。

奇偶的問題:可將數組拉伸成2x+1的長度,視爲兩數之間添入空數字,每個數/2可變回原來位置。割在數上兩邊各分一個,割在空數字上則正常左右分配。得到公式:LeftMax = (curIndex-1)/2,RightMin = curIndex/2。此時兩數組長度和爲2m+2n+2,找到m+n+1和m+n+2位置的數即可。代碼實際使用時直接用公式,所以可當空數字不存在。

二分法:找個長度短的數組進行,設爲A數組。則ALeftMax>BRightMin時,mid--,BLeftMax>ARightMin,mid++

python代碼:

import sys
class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        nums1Length = len(nums1)
        nums2Length = len(nums2)
        #保證nums1是短的
        if nums1Length > nums2Length:
            return self.findMedianSortedArrays(nums2,nums1)

        nums1LMax = nums2LMax = nums1RMin = nums2RMin = nums1Mid = nums2Mid = 0
        nums1Low = 0
        #放大成2倍
        nums1High = 2 * nums1Length
        while nums1Low <= nums1High:
            #總和是m+n+1個,mid爲索引值
            nums1Mid = (nums1Low + nums1High)//2
            nums2Mid = nums1Length + nums2Length - nums1Mid
            #當某數組數值全在中值左邊或右邊時,代表中值肯定在另一數組,令LMax<RMin
            nums1LMax = -sys.maxsize if nums1Mid == 0 else nums1[(nums1Mid-1)//2]
            nums2LMax = -sys.maxsize if nums2Mid == 0 else nums2[(nums2Mid-1)//2]
            nums1RMin = sys.maxsize if nums1Mid == 2*nums1Length else nums1[nums1Mid//2]
            nums2RMin = sys.maxsize if nums2Mid == 2*nums2Length else nums2[nums2Mid//2]
            #二分查找
            if(nums1LMax > nums2RMin):
                nums1High = nums1Mid - 1
            elif(nums2LMax > nums1RMin):
                nums1Low = nums1Mid + 1
            else:
                break
        return (max(nums1LMax,nums2LMax)+min(nums1RMin,nums2RMin))/2

      

反思:

太難了。。。

保證A數組最短方法,判斷長度,之後該函數參數的A、B互換

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章