題目來源:https://leetcode-cn.com/problems/median-of-two-sorted-arrays/submissions/python
給定兩個大小爲 m 和 n 的有序數組 nums1 和 nums2。算法
請你找出這兩個有序數組的中位數,而且要求算法的時間複雜度爲 O(log(m + n))。segmentfault
你能夠假設 nums1 和 nums2 不會同時爲空。數組
示例 1:bash
nums1 = [1, 3] nums2 = [2] 則中位數是 2.0
示例 2:微信
nums1 = [1, 2] nums2 = [3, 4] 則中位數是 (2 + 3)/2 = 2.5
這裏先理解中位數的概念:在統計學中,中位數指的是可將數值集合劃分爲相等的上下兩部分,其中一部分的元素總大於另外一部分的元素。spa
根據這個概念,咱們如今對兩個數組進行劃分,num1 數組用大寫 A 表示,num2 數組用大寫 B。這裏僅爲方便書寫。code
先對 A 進行劃分,在任意 i 處,將 A 劃分爲兩部分:blog
在任意 j 處,也對 B 進行劃分:leetcode
將 A 跟 B 兩個數組的左邊部分和右邊部分,各合在一塊
按照中位數的概念,只要保證左邊部分與右邊部分的長度相等,且左邊部分的最大數小於右邊部分的最小數,那麼就能夠求出中位數,即:
要知足上的兩個式子,必須知足下面的條件:
只要知足上面的等式就可以找到中位數。
第一個條件中,因爲 m + n 和的奇偶不定,分開分析:
由於 j 的取值爲整數,最終都會向下取整。可是這裏要注意,由於 j 的取值是不能爲負的。因此必須知足 m <= n
的前提,不然 j 有可能小於 0,這樣程序運行起來則會出錯。
這種狀況,即表示 i 的值太大,須要減少 i 的值,同時增大 j 的值。
上面是不考慮邊界的問題,下面講一下考慮邊界的狀況:
先考慮 i = 0,或者 j = 0,也就是在數組最前面劃分。這個時候,左邊部分當 j = 0 時,左邊最大值則是 A[i-1];當 i = 0 時,最大值就是 B[j-1]。
當 i = m 或者 j = n 的狀況下,也就是數組在最後面劃分。當 i = m 時,右邊最小值就是 B[j],當 j = n 時,右邊最小值就是 A[i]
上面就是考慮 i 爲 0 或者爲 m 的狀況。j 爲 0 或者 n 的狀況。這裏 i 在變化的時候,j 是否會越出邊界的問題,這個能夠不考慮,以下推導:
class Solution: def findMedianSortedArrays(self, nums1, nums2) -> float: m = len(nums1) n = len(nums2) # 這裏要始終知足 m <= n 的條件,防止運行出錯 if m > n: nums1, nums2, m, n = nums2, nums1, n, m # 這裏考慮的兩個數組爲空的狀態,直接拋出異常 if n == 0: raise ValueError # 只考慮 i 的取值,j 會隨之變化,且不會越界 i_min, i_max, half_len = 0, m, (m + n + 1) // 2 while i_min <= i_max: i = (i_min + i_max) // 2 j = half_len - i if i < m and nums2[j-1] > nums1[i]: # i 數值太小,增大 i i_min = i + 1 elif i > 0 and nums1[i-1] > nums2[j]: # i 數值過大,縮減 i i_max = i - 1 else: # 當 i 就是須要找的值時, # 考慮邊界在最前面切分時,左邊最大值的取值狀況 # 以及正常狀況下,左邊最大值的取值狀況 if i == 0: max_of_left = nums2[j-1] elif j == 0: max_of_left = nums1[i-1] else: max_of_left = max(nums1[i-1], nums2[j-1]) # 當爲奇數的狀況下,中位數就是左邊的最大值 if (m + n) % 2 == 1: return max_of_left # 當在最後面切分時,右邊最小值的狀況 # 以及正常狀況下的,右邊最小值的狀況 if i == m: min_of_right = nums2[j] elif j == n: min_of_right = nums1[i] else: min_of_right = min(nums1[i], nums2[j]) # 數組長度之和爲偶數的狀況下,返回左邊最大值和右邊最小值的平均值 return (max_of_left + min_of_right) / 2.0
以上就是《尋找兩個有序數組的中位數》第二種解法,根據中位數的概念。
歡迎關注微信公衆號《書所集錄》