兩個排序陣列的中位數

2021-09-08 17:37:09 字數 3146 閱讀 7571

中位數是將兩個集合劃分為兩個長度相等的子集,其中乙個子集的元素總是大於另乙個子集中的元素。

設兩個公升序排列的有序陣列a與b,a中包含m個元素,b中包含n個元素,請你找出這兩個有序陣列的中位數,並且要求演算法的時間複雜度為o(log(m + n))

a[0]………………a[i-1] | a[i]………………a[m-1]

b[0]………………b[j-1] | b[j]………………b[n-1]

記陣列a,b的長度分別為m,n,不妨設m<=n,a,b公升序排列。i,j分別將a,b分成兩個部分。a[i]左側的部分記作left_a,其他記作right_a,同理,b[j]左側的部分記作left_b,其他記作right_b。為保證上述的條件,我們在**中做如下處理:

/

*** 確保a的長度小於等於b的長度 */

int m = a.length;

int n = b.length;

if(m > n)

對於a,b有四種情況:

[1]、m+n是偶數時,m是偶數,n是偶數

[2]、m+n是偶數時,m是奇數,n是奇數

[3]、m+n是奇數時,m是偶數,n是奇數

[4]、m+n是偶數時,m是奇數,n是偶數

現在假設一種理想的情況,令i=m/2,j=(m+n)/2-i,且a[i]>=b[j-1],a[i-1]<=b[j],即left_a+left_b全部小於a[i]和b[j],由i與j的位置可知,對於[1]、[2] ,left_a+left_b=right_a+right_b,對於[3]、[4],left_a+left_b+1=right_a+right_b,因為中位數被放到了右側的部分,此時

對於[1]、[2]兩種情況,中位數

對於[3]、[4]兩種情況,中位數

但實際上如此理想的情況基本不會存在,因此我們需要調整i,j的位置。

當a[i]b[j]時,必然有a[i]>b[j-1],這時,需要減小i。令i=i-1,j=j+1。

調整i,j的位置後,重新判斷是否滿足條件a[i]>=b[j-1],a[i-1]<=b[j]。

所以上述過程可以寫作如下的形式,

1、if a[i]>=b[j-1],a[i-1]<=b[j]

if m+n是偶數

median=(max(a[i-1],b[j-1])+min(a[i],b[j]))/2

if m+n是奇數

min(a[i],b[j])

2、if a[i]b[j]

i=i-1,j=j+1

重複1

while

(i>=0&

&ielse

if(a[i]

)else

if(a[i-1]

>b[j])}

}

當然上面沒有考慮邊界的情況,即i=0和i=m-1時的情況,下面討論邊界的情況。

當i=0時,i-1會超出陣列a的下界,這時我們只需判斷a[i]>=b[j-1]是否成立,若有a[i]>=b[j-1]

if m+n是偶數

median=(b[j-1]+min(a[i],b[j]))/2

if m+n是奇數

median=min(a[i],b[j])

if

(i==0)

}

若a[i]> b[j],這時,i需要繼續減小,i會小於0,出現這種情況時, a中的元素全部大於b中的元素。

當i=m-1時,i-1不會超出下界,只需注意a[m-1]<=b[0]時的情況,當a[m-1]<=b[0]時,a中的元素全部小於b。

我們需要注意j的值是否超過上界或者下界嗎?

當m/**

* 處理a全部大於b或a全部小於b的情況

*/if

(a[0

]>=b[n-1]

) = a[0],min = b[n-1]

return

(a[0

]+ b[n -1]

)/2.0;

}else

}else

}else

if(a[m-1]

<=b[0]

) = a[m-1],min = b[0]

return

(a[m-1]

+ b[0]

)/2.0;

}else

}else

}同時,我們要注意到,要求時間複雜度為o(log(m + n)),所以在增大或者減小i時我們採用二分查詢。我們知道二分查詢的時間複雜度為o(log(2n)),採用二分查詢的方法,時間複雜度為o(log(m))。

if

(a[i]

)else

if(a[i-1]

>b[j]

)

private static double findmediansortedarrays(

int[

] a,

int[

] b)/**

* 處理a全部大於b或a全部小於b的情況

*/if

(a[0

]>=b[n-1]

)= a[0]

,min

= b[n-1]

return

(a[0

]+ b[n -1]

)/2.0;

}else

}else

}else

if(a[m-1]

<=b[0]

)= a[m-1]

,min

= b[0]

return

(a[m-1]

+ b[0]

)/2.0;

}else

}else

}int

max= m;

intmin=0

;int i =

(max

+min)/

2;int j =

(m+n)/2

-i;while

(i>=0&

&i(i-1

>=0)

else

if(a[i]

)else

if(a[i-1]

>b[j])}

}return

0.0;

}

兩個排序陣列的中位數

求兩個排序陣列中位數,這道題是很有意思的一道題目,演算法導論中9.3 8題,這題必須在o logn 的時間複雜度求解,否則肯定悲劇。這題有個關鍵的條件,那就是這兩個陣列長度相等 思路如下 陣列a 1,3,5,7,9 陣列b 2,4,6,8,10 首先取二者的中位數,在o 1 時間複雜度內求出,那麼陣...

兩個排序陣列的中位數

求兩個排序陣列中位數,這道題是很有意思的一道題目,演算法導論中9.3 8題,這題必須在o logn 的時間複雜度求解,否則肯定悲劇。這題有個關鍵的條件,那就是這兩個陣列長度相等 思路如下 陣列a 1,3,5,7,9 陣列b 2,4,6,8,10 首先取二者的中位數,在o 1 時間複雜度內求出,那麼陣...

兩個排序陣列的中位數

兩個排序的陣列a和b分別含有m和n個數,找到兩個排序陣列的中位數,要求時間複雜度應為o log m n 給出陣列a 1,2,3,4,5,6 b 2,3,4,5 中位數3.5 給出陣列a 1,2,3 b 4,5 中位數 3 public double findmediansortedarrays in...