題目:
給定兩個大小爲 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互換