两个排序数组合并第k或前k个最小值问题
求最小一般用二分,求前最小一般用堆
偶爾看到一個問題,搜索了一些解法,用來存著
1.X[1..n] 和 Y[1..n]為兩個數組,每個都包含n個已排好序的數。給出一個求數組X和Y中所有2n個元素的中位數的O(lgn)時間的算法
?
參考 :http://blog.csdn.net/zhanglei8893/article/details/6314002
分析與解答:
?? ?? 若中位數位于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) 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.假設a[m],?b[n]是兩個排好序的數組,并且沒有重復元素,要找第k小的元素
參考: http://bbs.csdn.net/topics/370014294
里面有一種方法挺好的,O(lgk)
為了方便以下描述下標從1開始,
如果m,n>=k時,若k為偶數取i=k/2,j=k/2,若k為奇數,一個向下去整一個向上去整。如果兩個值相同,則第k小的就是此值;如果此時一大一小,假設a[i]>b[j],則i--,j++(0<i,j<n)直到a[i]<=b[j],則b[j]即為第k小的值。
如果m,n<k,則只要取的兩個下標i+j=k即可,方法相同。
3.兩個按升序排好的等長數組A[K],B[K]。A[i]+B[j],其中,0<i<K,0<j<K.(數組從0開始的)求前K個小的 A[i]+B[j],(注意:不是第K個,是前K個,輸出結果沒要求一定是排好序的,但要求空間復雜度和時間復雜度盡可能最優)
?
開始考慮最小的肯定為A[0]+B[0],如果第k小的是A[m]+B[n],當i<=m,j<=n時,A[i]+B[j]必<=A[m]+B[n],必是在前k個最小的數中,則m*n<=k。(后面不會想了)
參考:http://blog.csdn.net/sunnianzhong/article/details/8932374
如果用最小堆求解思路如下:
首先把a0+b0的結果放入堆中,此時堆中只有一個元素,自然滿足最小堆條件,然后開始出堆的操作,從堆里面取出根節點(也就是最小的值),
例如是a[i]+b[j],則需要像最小堆中壓入a[i+1]b[j] 和?a[i]+b[j+1],當然,要保證下標不越界,如果下標越界了則忽略,另外要保證已經壓入過堆中的組合(即使已經從堆中被取出了的)不再被壓入堆中。不段進行出堆、入堆的操作,重復K次,就得到了K個最小的組合值。
堆的最大深度為logK,所以時間復雜度為K*logK數量級。
空間復雜度O(K)
開始感覺這個思路貌似有問題,感覺局部最小值不一定為全局最小值,但是看完楊氏矩陣又想了想,還是對的,每次搜索都是候選最小值,出堆的是全局最小值。
已知一個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個數組,每個數組有k個整數。每個數組中選取一個整數,一共k個整數,取其和,一共可以得到k^k個和。給出方法,求得這k^k個和中,最小的k個。
?
這個題目最終歸于第三題,對兩個數組求和的最小的k個,求出的k個值作為一個數組再與第三個數組求最小的k個,以此類推。
最后的時間復雜度是O(k^2logk)。
?
?
?
總結
以上是生活随笔為你收集整理的两个排序数组合并第k或前k个最小值问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: abort has been calle
- 下一篇: opencv KNN 模型不能保存的问题