4. 尋找兩個有序陣列的中位數
給定兩個大小為 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
from typing import list
class
solution
:def
findmediansortedarrays
(self, nums1: list[
int]
, nums2: list[
int])-
>
float
: nums1 = nums1 + nums2
nums1.sort(
) i =
(len
(nums1)-1
)//2#由於中位數有的是要計算左右兩數的平均值
j =len(nums1)//2
#所以當列表的個數為偶數的時候,需要進行平均值計算
value =
(nums1[i]
+ nums1[j])/
2return value
if __name__ ==
"__main__"
: nums1 =[1
,2] nums2 =[3
,4] solution = solution(
) output = solution.findmediansortedarrays(nums1, nums2)
print
(output)
顯然上述的解法是o((m+n) log (m+n))的,不滿足題意,看到log應該考慮使用二分查詢。
看看威威哥的題解之後在這裡記錄一下。
由於兩個陣列是有序的,那麼我們找出來的中位數的次序是固定的,我們可以通過從頭開始比較兩個陣列元數進行計數,找到中位數。但是這樣的時間複雜度是o(m+n),也是不滿足題意的。
承接上面的思路,我們可以在兩個陣列中各自劃分一條線,把陣列變成左右兩邊。只要兩個陣列的左邊個數等於右邊的個數和。或者兩個陣列的左邊個數和 等於 右邊個數和加一,那麼我們就可以求的中位數了。
還是一步一步分析,首先看看兩個陣列個數和為奇數的情況
如上圖所示,為奇數個數的時候,分割線左邊的個數和始終要大於右邊的個數和加乙個。我們的中位數就在兩個分割線左邊值裡面去乙個最大數。
如果兩個陣列之和是偶數,那麼根據上面的分割關係,左右兩邊的個數相等,中位數就是中間的兩個數取平均值。但是由於分割線左右兩邊有四個元素,我們應該取左邊的最大值, 右邊的最小值計算平均。
使用二分法:
邊界的取值:知道使用二分之後,我們來確定一下邊界:
實現的**如下:
class
solution
:def
findmediansortedarrays
(self, nums1: list[
int]
, nums2: list[
int])-
>
float
: n1 =
len(nums1)
n2 =
len(nums2)
if n1 > n2:
nums1, nums2 = nums2, nums1
n1, n2 = n2, n1
left, right =
0, n1
while left < right:
#進行二分查詢
i =(left + right)//2
j =(n1 + n2 +1)
//2- i#這裡多加乙個1,意味著左邊個數等於,或者比右邊個數多個1
if nums1[i]
< nums2[j-1]
: left = i +
1else
: right = i
i = left
j =(n1 + n2 +1)
//2-i #左邊越界的時候取負無窮
m1 = nums1[i-1]
if i >
0else
-float
('inf'
) m2 = nums2[j-1]
if j >
0else
-float
('inf')if
(n1+n2)%2
==1:return
max(m1, m2)
#為奇數個的時候, 取左邊界的最大值
#右邊越界的時候取正無窮
m3 = nums1[i]
if i < n1 else
float
('inf'
) m4 = nums2[j]
if j < n2 else
float
('inf')if
(n1+n2)%2
==0:#為偶數個的時候,取左邊界的最大值,右邊界的最小值,兩者求乙個平均
return
(max
(m1, m2)
+min
(m3,m4))/
2
LeetCode 4 尋找兩個有序陣列的中位數
給定兩個大小為 m 和 n 的有序陣列 nums1 和 nums2。請你找出這兩個有序陣列的中位數,並且要求演算法的時間複雜度為 o log m n 你可以假設 nums1 和 nums2 不會同時為空。示例 1 nums1 1,3 nums2 2 則中位數是 2.0 示例 2 nums1 1,2 ...
LeetCode 4 尋找兩個有序陣列的中位數
給定兩個大小為 m 和 n 的有序陣列nums1和nums2。請你找出這兩個有序陣列的中位數,並且要求演算法的時間複雜度為 o log m n 你可以假設nums1和nums2不會同時為空。示例 1 nums1 1,3 nums2 2 則中位數是 2.0示例 2 nums1 1,2 nums2 3,...
LeetCode4 尋找兩個有序陣列的中位數
給定兩個大小為 m 和 n 的有序陣列nums1和nums2。請你找出這兩個有序陣列的中位數,並且要求演算法的時間複雜度為 o log m n 你可以假設nums1和nums2不會同時為空。示例 1 nums1 1,3 nums2 2 則中位數是 2.0示例 2 nums1 1,2 nums2 3,...