9.3-8 設X[1..n] 和 Y[1..n]為兩個數組,每個都包含n個已排好序的數。給出一個求數組X和Y中所有2n個元素的中位元的O(lgn)時間的演算法
分析與解答:
若中位元位於X中,不妨設為X[k],即在X中有k個元素小於等於中位元,n-k個元素大於等於中位元。由於X[k]為合并後的2n個元素的中位元,則在Y中有n-k個元素小於等於中位元,k個元素大於等於中位元,即
Y[n-k] ≤ X[K] ≤ Y[n-k+1]
看到時間複雜度為O(lgn),不禁使我們想到二分法,但是和這題有什麼關聯呢?
二分法每次搜尋都能減小一半的範圍,在搜尋中位元的過程也可以的,下面具體論述:
若X[k]不滿足上述等式,分兩種情況
(1) X[k] < Y[n-k]
若中位元是k' < k,則X[k'] ≤ X[k]] < Y[n-k] 。那麼在Y中小於等於X[k']的元素數目小於n-k,則X[k']不可能為中位元
由此只需要搜尋k' > k的範圍
(2) X[k] > Y[n-k+1]
若中位元是k' > k,則X[k'] > X[k] > Y[n-k+1] 。那麼在Y中小於等於X[k']的元素數目大於n-k+1,則X[k']不可能為中位元
由此只需要搜尋k' < k的範圍
根據上述特點,我們可以採用二分搜尋逐步縮小搜尋範圍。
整個演算法的過程如下:
TWO-ARRAY-MEDIAN(X, Y)<br />n ← length[X]<br />median ← FIND-MEDIAN(X, Y, n, 1, n)<br />if median = NOT-FOUND<br /> then median ← FIND-MEDIAN(Y, X, n, 1, n)<br />return median</p><p>FIND-MEDIAN(A, B, n, low, high)<br />if low > high<br /> then return NOT-FOUND<br />k ← (low + high)/2<br />if k=n and A[n] ≤ B[1]<br /> then return A[n]<br />elseif k<n and B[n-k]≤A[k]≤B[n-k+1]<br /> then return A[k]<br />elseif A[k]<B[n-k]<br /> then return FIND-MEDIAN(A, B, n, k+1, high)<br />else return FIND-MEDIAN(A, B, n, low, k-1)