題目要求時間複雜度為log(m+n)。
可以將此題轉換成尋找第k小的數的問題!
演算法的原理:
假設要找第k
小的數,我們要比較
a[k/2-1]
和b[k-k/2-1]
這兩個元素,這兩個元素分別表示a
的第k/2
小的元素和b的第
k-k/2
小的元素。至於為什麼要去這兩個數,是因為
k/2+(k-k/2)等於k
,所以去這兩個數比較。
這兩個元素比較共有三種情況:>
、《和=
: 如果a[k/2-1],這表示
a[0]
到a[k/2-1]
的元素都在a和
b合併之後的前
k小的元素中,直接拋棄即可。
如果a[k/2-1]>b[k/2-1]
時存在類似的結論。
如果a[k/2-1]=b[k/2-1]
時,我們已經找到了第
k小的數,也即這個相等的元素
通過上面的分析,我們即可以採用遞迴的方式實現尋找第k
小的數。此外我們還需要考慮幾個邊界條件:
如果a或者b
為空,則直接返回
b[k-1]
或者a[k-1];
如果k為
1,我們只需要返回
a[0]
和b[0]
中的較小值;
完整**:
public static double findmediansortedarrays(int a, int m, int b, int n)
public static double findkth(int a, int m, int b, int n, int k, int head_a, int head_b)
**解釋:
①head_a
和head_b
②pa和pb
:計算理論上要比較的兩個元素的位置
③new_pa
和new_pb
:因為拋棄元素後,陣列的起始位置往後移了,所以需要重新計算要比較的兩個元素的實際所在位置
④在遞迴呼叫findkth()
方法時,引數的解釋:
m-pa
表示拋棄元素後陣列
a剩餘元素的長度;
k-pa
表示因為拋棄了
pa個元素,所以不能再尋找第
k小的數了要變成尋找第
k-pa
小的數;拋棄
pa個元素後,陣列
a的起始是從
head_a += pa開始
在最好情況下,每次都有k
一半的元素被刪除,所以演算法複雜度為
logk
,由於求中位數時k為(
m+n)
/2,所以演算法複雜度為
log(m+n)。
連線:
兩個有序陣列中位數
大小m和n分別有兩個排序陣列a和b。找到兩個排序陣列的中值。總的執行時間複雜度應該是o log m n class solution return findkth a,b,0,0,m,n,s 2 findkth a,b,0,0,m,n,s 2 1 2 private double findkth v...
兩個有序陣列中位數
首先我們可以不斷分割得到這個kkk。首先兩個陣列都分配k 2 frac 2k 如果第k 2 frac 2k 個數,第乙個陣列小於第二個陣列,那麼第乙個陣列的k 2 frac 2k 個數一定不是答案。問題可以變成乙個子問題,上乙個陣列從k2 1 frac 1 2k 1開始。相當於我們每次要去掉k 2 ...
兩個有序陣列的中位數
問題一 兩個有序陣列,且長度都為n。找出中位數。解決這個問題的方法很多。方法一 基於歸併排序的merge方法。找出兩個陣列中第n大的數和第n 1大的數,然後求它們的平均數。時間複雜度為o n 方法二 比較兩個陣列中的中位數的大小。每一次比較都能縮小兩個陣列的搜尋範圍。時間複雜度為o nlgn pub...