两个排序数组合并第k或前k个最小值问题
求最小一般用二分,求前最小一般用堆
偶爾看到一個(gè)問題,搜索了一些解法,用來存著
1.X[1..n] 和 Y[1..n]為兩個(gè)數(shù)組,每個(gè)都包含n個(gè)已排好序的數(shù)。給出一個(gè)求數(shù)組X和Y中所有2n個(gè)元素的中位數(shù)的O(lgn)時(shí)間的算法
?
參考 :http://blog.csdn.net/zhanglei8893/article/details/6314002
分析與解答:
?? ?? 若中位數(shù)位于X中,不妨設(shè)為X[k],即在X中有k個(gè)元素小于等于中位數(shù),n-k個(gè)元素大于等于中位數(shù)。由于X[k]為合并后的2n個(gè)元素的中位數(shù),則在Y中有n-k個(gè)元素小于等于中位數(shù),k個(gè)元素大于等于中位數(shù),即
?????????????????????????????????????? Y[n-k] ≤? X[K] ≤ Y[n-k+1]
看到時(shí)間復(fù)雜度為O(lgn),不禁使我們想到二分法,但是和這題有什么關(guān)聯(lián)呢?
二分法每次搜索都能減小一半的范圍,在搜索中位數(shù)的過程也可以的,下面具體論述:
若X[k]不滿足上述等式,分兩種情況
(1) X[k] < Y[n-k]
???? 若中位數(shù)是k' < k,則X[k'] ≤? X[k]] < Y[n-k] 。那么在Y中小于等于X[k']的元素?cái)?shù)目小于n-k,則X[k']不可能為中位數(shù)
???? 由此只需要搜索k' > k的范圍
(2) X[k] > Y[n-k+1]
???? 若中位數(shù)是k' >? k,則X[k'] > X[k] > Y[n-k+1] 。那么在Y中小于等于X[k']的元素?cái)?shù)目大于n-k+1,則X[k']不可能為中位數(shù)
???? 由此只需要搜索k' < k的范圍
根據(jù)上述特點(diǎn),我們可以采用二分搜索逐步縮小搜索范圍。
整個(gè)算法的過程如下:
TWO-ARRAY-MEDIAN(X, Y) n ← length[X] median ← FIND-MEDIAN(X, Y, n, 1, n) if median = NOT-FOUNDthen median ← FIND-MEDIAN(Y, X, n, 1, n) return medianFIND-MEDIAN(A, B, n, low, high) if low > highthen return NOT-FOUND k ← (low + high)/2 if k=n and A[n] ≤ B[1]then return A[n] elseif k<n and B[n-k]≤A[k]≤B[n-k+1]then return A[k] elseif A[k]<B[n-k]then return FIND-MEDIAN(A, B, n, k+1, high) else return FIND-MEDIAN(A, B, n, low, k-1)?
?
2.假設(shè)a[m],?b[n]是兩個(gè)排好序的數(shù)組,并且沒有重復(fù)元素,要找第k小的元素
參考: http://bbs.csdn.net/topics/370014294
里面有一種方法挺好的,O(lgk)
為了方便以下描述下標(biāo)從1開始,
如果m,n>=k時(shí),若k為偶數(shù)取i=k/2,j=k/2,若k為奇數(shù),一個(gè)向下去整一個(gè)向上去整。如果兩個(gè)值相同,則第k小的就是此值;如果此時(shí)一大一小,假設(shè)a[i]>b[j],則i--,j++(0<i,j<n)直到a[i]<=b[j],則b[j]即為第k小的值。
如果m,n<k,則只要取的兩個(gè)下標(biāo)i+j=k即可,方法相同。
3.兩個(gè)按升序排好的等長數(shù)組A[K],B[K]。A[i]+B[j],其中,0<i<K,0<j<K.(數(shù)組從0開始的)求前K個(gè)小的 A[i]+B[j],(注意:不是第K個(gè),是前K個(gè),輸出結(jié)果沒要求一定是排好序的,但要求空間復(fù)雜度和時(shí)間復(fù)雜度盡可能最優(yōu))
?
開始考慮最小的肯定為A[0]+B[0],如果第k小的是A[m]+B[n],當(dāng)i<=m,j<=n時(shí),A[i]+B[j]必<=A[m]+B[n],必是在前k個(gè)最小的數(shù)中,則m*n<=k。(后面不會(huì)想了)
參考:http://blog.csdn.net/sunnianzhong/article/details/8932374
如果用最小堆求解思路如下:
首先把a(bǔ)0+b0的結(jié)果放入堆中,此時(shí)堆中只有一個(gè)元素,自然滿足最小堆條件,然后開始出堆的操作,從堆里面取出根節(jié)點(diǎn)(也就是最小的值),
例如是a[i]+b[j],則需要像最小堆中壓入a[i+1]b[j] 和?a[i]+b[j+1],當(dāng)然,要保證下標(biāo)不越界,如果下標(biāo)越界了則忽略,另外要保證已經(jīng)壓入過堆中的組合(即使已經(jīng)從堆中被取出了的)不再被壓入堆中。不段進(jìn)行出堆、入堆的操作,重復(fù)K次,就得到了K個(gè)最小的組合值。
堆的最大深度為logK,所以時(shí)間復(fù)雜度為K*logK數(shù)量級(jí)。
空間復(fù)雜度O(K)
開始感覺這個(gè)思路貌似有問題,感覺局部最小值不一定為全局最小值,但是看完楊氏矩陣又想了想,還是對的,每次搜索都是候選最小值,出堆的是全局最小值。
已知一個(gè)2維矩陣,其中的元素每一行從左至右依次增加,每一列從上到下依次增加。即對于矩陣Table有Table[i][j] ≤Table[i][j + 1], Table[i][j] ≤ Table[i + 1][j],我們也稱這樣的矩陣為楊氏矩陣。
楊氏矩陣參考http://blog.csdn.net/michealmeng555/article/details/2489923
?
4.給定k個(gè)數(shù)組,每個(gè)數(shù)組有k個(gè)整數(shù)。每個(gè)數(shù)組中選取一個(gè)整數(shù),一共k個(gè)整數(shù),取其和,一共可以得到k^k個(gè)和。給出方法,求得這k^k個(gè)和中,最小的k個(gè)。
?
這個(gè)題目最終歸于第三題,對兩個(gè)數(shù)組求和的最小的k個(gè),求出的k個(gè)值作為一個(gè)數(shù)組再與第三個(gè)數(shù)組求最小的k個(gè),以此類推。
最后的時(shí)間復(fù)雜度是O(k^2logk)。
?
?
?
總結(jié)
以上是生活随笔為你收集整理的两个排序数组合并第k或前k个最小值问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: abort has been calle
- 下一篇: opencv KNN 模型不能保存的问题