給定兩個大小為 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
題目要求將時間複雜度降低到o(log(m+n)),如果對時間複雜度的要求有log,通常都需要用到二分查詢,這道題也是通過二分查詢實現
根據中位數的定義,當m+n是奇數的時候,中位數是兩個有序陣列中的第(m+n)/2個元素,當m+n是偶數的時候,中位數是兩個有序陣列中的第(m+n)/2和第(m+n)/2+1個元素的平均值。因此,這道題可以轉換為尋找兩個有序陣列中的第k小的數,其中k為(m+n)/2或者(m+n)/2+1
假設有序陣列分別是a和b要找到第k個元素,我們可以比較a[k/2-1]和b[k/2-1],其中/標識除法符號。由於a[k/2-1]和b[k/2-1]的前面分別有a[0 … k/2-2]和b[0 … k/2-2],即k/2-1個元素,對於a[k/2-1]和b[k/2-1]中的較小值,最多只有(k/2-1)+(k/2-1) <=k-2個元素比他小,那麼他就不是第k個小的數
因此我們可以歸納出三種情況
可以看到,比較a[k/2-1]和b[k/2-1]之後可以排除k/2個可能是第k小的數,查詢範圍小了一半.同時,我們將在排除後的新陣列上繼續進行二分查詢,並且根據我們排除的個數,減小k的值,這是因為我們排除的數都是不大於第k小的數字
有以下三種情況需要特殊處理
package 題庫.尋找兩個正序陣列中位數;
public
class
solution
;int
num2=
; solution solution =
newsolution()
; system.out.
println
(solution.
findmediansortedarrays
(num1,num2));
}/**
* 在兩個正向陣列中獲得中位數
* @param num1
* @param num2
* @return
*/private
double
findmediansortedarrays
(int
num1,
int[
] num2)
else
}/**
* 二分查詢法
* @param a
* @param b
* @param k 需要查詢的第k個元素
* @return
*/public
double
binarysearch
(int
a,int[
]b,int k)
//b陣列索引等於b陣列的長度
if(bi == bl)
//第k個字元是不是第乙個
if(k ==1)
//常規操作,獲取第k/2個元素的索引或者如果超出界限獲取該陣列最後乙個元素
nai = math.
min(ai+k/
2, al)-1
; nbi = math.
min(bi+k/
2, bl)-1
;//兩種常規情況
//該索引a陣列大於b陣列
if(a[nai]
>= b[nbi]
)else}}
}
力扣演算法篇 尋找兩個正序陣列的中位數
尋找兩個正序陣列的中位數 給定兩個大小分別為m和n的正序 從小到大 陣列nums1和nums2。請你找出並返回這兩個正序陣列的中位數。例項 題解 遍歷兩個陣列 得到有序的合併陣列並找到中位數 class solution vector int combine int i 0 int j 0 whil...
力扣第4題 尋找兩個正序陣列的中位數
給定兩個大小為 m 和 n 的正序 從小到大 陣列 nums1 和 nums2。請你找出並返回這兩個正序陣列的中位數。高階 你能設計乙個時間複雜度為 o log m n 的演算法解決此問題嗎?示例 1 輸入 nums1 1,3 nums2 2 輸出 2.00000 解釋 合併陣列 1,2,3 中位數...
尋找兩個正序陣列的中位數
尋找兩個正序陣列的中位數 二分法根據中位數的定義,當 m n 是奇數時,中位數是兩個有序陣列中的第 m n 2 個元素,當 m n 是偶數時,中位數是兩個有序陣列中的第 m n 2 個元素和第 m n 2 1 個元素的平均值。因此,這道題可以轉化成尋找兩個有序陣列中的第 k 小的數,其中 k 為 m...