兩個有序的數組 nums1 和 nums2 ,它們的數組長度分別爲 m 和 n。要求找到這兩個數組的中位數,且整體的時間複雜度必須爲 。python
假設 nums1 和 nums2 都不爲空。算法
例 1:數組
nums1 = [1, 3]
nums2 = [2]
中位數爲 2.0
複製代碼
例 2:bash
nums1 = [1, 2]
nums2 = [3, 4]
中位數爲 (2 + 3)/2 = 2.5
複製代碼
Hard
ide
作第一遍時,使用的遍歷的辦法,即按照從小到大的順序,分別遍歷兩個隊列,一直遍歷到 的位置,便是咱們所要的中位數,當時心想,這也太簡單了吧,Hard
級別也不過如此。spa
再仔細看題目,它還有個時間複雜度爲 的要求,而個人方案的時間複雜度卻爲 ,並不知足題目條件,可見,單這個條件就值 Hard
級別了。code
解這道題的關鍵並非高超的算法,而是心中要有一副這樣的圖:隊列
left side | right side
nums1: A(0),A(1),...,A(i-1) | A(i),...,A(m-1)
nums2: B(0),B(1),...,B(j-1) | B(j),...,B(n-1)
複製代碼
咱們把兩個數組當作一個總體,有一根豎線將其中的元素從中間分開,且左邊的部分和右邊部分的元素相同(總數爲奇數狀況下,左邊比右邊多 1 個元素),那麼當 爲偶數時,中位數爲 ,當 爲奇數時,中位數爲 leetcode
咱們都知道,左邊的元素爲 個,而左右兩邊元素相同,則get
咱們能夠用 i 來表示 j,則
因此,該題就變成了,在數組 A 中尋找一個 i,使得 ,且 成立,這兩個不等式的含義是,豎線右邊最小的數必定不比左邊最大的數小,知足該條件,咱們就能夠說找到了這個豎線。
咱們在找 i 的過程當中,不免會碰到 時候,此時咱們須要將 i 向右移,使 增大,當 i 右移,i 增大的同時,j 會減小,即 的值會變小,這樣操做 i 以後,會讓咱們更接近目標;同理,當 時,咱們須要將 i 向左移。
經過上面的分析,咱們最終可使用二分查找法來尋找這個 i 值,又因爲二分查找的時間複雜度爲 ,這種方法能夠知足題目的要求。
思路說完了,下面來講下該題目的邊界條件,因爲 j 是經過減去 i 算出來的,而 i 的最大值爲 m(A 全在左邊時),因此爲了使 j 不爲負數,數組 A 須要爲兩個數組中,元素數較少的那個。
當 i 爲 0 時,數組 A 全在右邊,咱們只須要判斷 成立;當 i 爲 m 時,數組 A 全在左邊,只需判斷 成立
同理當 j 爲 0 時,數組 B 全在右邊,咱們只需判斷 成立;當 j 爲 n 時,數組 B 全在左邊,只需判斷 便可
因而,咱們能夠寫出下面的代碼:
class Solution(object):
def findMedianSortedArrays(self, nums1, nums2):
m, n = len(nums1), len(nums2)
if m > n:
m, n, nums1, nums2 = n, m, nums2, nums1
if m == 0 and n == 0:
return None
begin = 0
end = m
i = j = 0
while True:
i = (begin + end) / 2
j = (m + n + 1) / 2 - i
if (i == 0 or j == n or nums2[j] >= nums1[i-1]) and\
(i == m or j == 0 or nums1[i] >= nums2[j-1]):
left_max = 0
if i == 0: left_max = nums2[j-1]
elif j == 0: left_max = nums1[i-1]
else: left_max = max(nums1[i-1],nums2[j-1])
if (m+n)%2 != 0:
return left_max
right_min = 0
if i == m: right_min = nums2[j]
elif j == n: right_min = nums1[i]
else: right_min = min(nums1[i], nums2[j])
return (left_max + right_min)*1.0/2
elif j < n and i > 0 and nums2[j] < nums1[i-1]:
end = i - 1
elif j > 0 and i < n and nums1[i] < nums2[j-1]:
begin = i + 1
複製代碼
這道題直接看代碼是很難理解的,但若是心中有前文說的那張圖,即可以沿着思路慢慢化解,可見要達到題目的要求並不簡單,Hard
難度名不虛傳。