LeetCode千題斬之找出兩個有序陣列的中位數
題目: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)).
You may assume nums1 and nums2 cannot be both empty.
有兩個排好序的陣列(可以假設兩個陣列均為非空),找到這兩個陣列元素合在一起的中位數。執行時間複雜度應該在O(log (m+n)).
思路:首先要深刻理解一下中位數的含義,就是把一個數組分成兩個相同長度的子陣列,左邊陣列元素均小於右邊陣列元素。
兩個陣列記為A與B,大小為m與n,先假設m<n。
則相當於可以使用兩塊木板把陣列A,B分成兩部分,
left_part | right_part A[0], A[1], ..., A[i-1] | A[i], A[i+1], ..., A[m-1] B[0], B[1], ..., B[j-1] | B[j], B[j+1], ..., B[n-1]
當滿足i+j=(m+n+1)/2(偶數時left_part元素個數為總數一半,總數目為奇數時left_part元素個數為一半向上取整),
且len(left_part)=len(right_part)
max(left_part)≤min(right_part)
則成功滿足了題目條件,median=max(left_part)+min(right_part)/2。
於是可選擇變數i,j,因為對陣列A的劃分只有0,1,2...m中(想像成往元素中間插木板),所有i取0~m,i+j=(m+n+1)/2。使用二分法進行迴圈。
考慮了大體的思路後需要考慮可能出現的極端情況,最直接的想法就是兩塊木板插入的位置剛好在陣列首與尾,此時將會有陣列A或B劃分後左右一端為空的情況。程式碼如下。
def findMedianSortedArrays( nums1, nums2):
"""
:type nums1: List[int]
:type nums2: List[int]
:rtype: float
"""
len1=len(nums1)
len2=len(nums2) #預設len2<=len1
halflen=int((len1+len2+1)/2)
if len1<len2:
nums1,nums2,len1,len2=nums2,nums1,len2,len1 #交換num1與nums2
imin,imax=0,len2
while imin<=imax:
i = int((imin + imax) / 2)
j = halflen - i
print(i,j)
if i<len2 and nums1[j-1]>nums2[i]:
imin+=1
elif i>0 and nums2[i-1]>nums1[j]:
imax-=1
else:
if i == 0:
max_of_left = nums1[j - 1]
elif j == 0:
max_of_left = nums2[i - 1]
else:
max_of_left = max(nums1[j- 1], nums2[i - 1])
if (len1 + len2) % 2 == 1:
return max_of_left
if i == len2:
min_of_right = nums1[j]
elif j == len1:
min_of_right = nums2[i]
else:
min_of_right = min(nums1[j], nums2[i])
return (max_of_left + min_of_right) / 2.0