如何排序n個排序列表,其平均長度K在O(n * log K)時間?如何將n個排序列表中的平均長度K排序爲O(n * log K)時間?
回答
正如在你的問題的評論中所提到的,O(nlog(k))是不可能的,但這裏有幾個關於this page的算法可以有效地完成你的任務;這裏是一個:
取每個列表中的第一個元素 並創建一個堆(大小爲k)。彈出 最小的元素。從 查找數組元素來(假設它來自列表編號我 )。從列表i中取下一個 元素,並將其推入 堆。對於 合併列表中的每個元素,我們花費了log(k)時間。所以 的時間複雜度是O(N * logk)其中 N是 中所有K列表中元素的總數。
-written由:Abhishek Goyal
感謝您的投入士兵和阿布舍克。這是一個適當的解決方案 – 2010-03-20 06:18:17
當你說它不可能你能提供一個證明嗎?否則,請說我不知道有這樣的方式。像那些沒有證據的聲明只是阻礙了進步。 – ldog 2011-10-31 06:22:56
@ldog:查看關於問題的評論。如果可能的話,那麼你可以合併O(log k)中的兩個排序列表,這意味着你可以做兩個列表的子線性合併,這顯然是不可能的。它也意味着比較排序比O(n log n)更好,另一件事情被證明是不可能的。 – 2014-05-11 15:36:00
您可以調整合並排序來完成這項工作。合併排序利用將已排序的列表合併成新的排序列表的便利。
不,你不能。合併是O(K)。 – 2010-03-20 05:19:04
沒有定義它,它會像nK * log(nK)那樣,因爲你基本上只是將所有數組的長連接列表合併在一起。 – freeall 2012-12-12 13:45:53
合併排序是關鍵。讓假設N是元件的總數是統一和K容器的含有它們的數量:你在追加單個載體的所有已排序的序列,但其中記住你所附他們
。更好的辦法是,如果你按照它們的第一個元素的值排序,它們會加速下一段。
然後你合併排序的序列對(std :: inplace_merge,如果你使用C++)。每一次合併都是Na + Nb,所以每一步都是N.你必須執行logK步驟。
因此NlogK。
我相信有可能實現O(N * log(K)),但不是在最壞的情況下。
考慮排序這些列表:
{0,1,2,3,4,5,6,7,8,9,10},
{10,11,12,13,14,15,16,17,18,19,20},
{20,21,22,23,24,25,26,27,28,29,30}
我的人的大腦可以很容易地不讀每一個值的列表進行排序,所以應該有一個算法,可以做同樣的。我們需要合併,同時使用修改的二進制搜索來查找值的範圍。
在最壞的情況下,你得到O(N * K),因爲每個值都必須進行比較。例如:
{0,2,4,6,8},
{1,3,5,7,9}
這是我在圍棋的解決方案,如果我知道的有序列表我只會用通常是相對較小的K重疊區域:
// variation of binary search that finds largest
// value up to and including max
func findNext(a []int, imin int, vmax int) int {
imax := len(a) - 1
best := -1
for imin <= imax {
imid := imin + ((imax - imin)/2)
if a[imid] == vmax {
return imid
} else if a[imid] < vmax {
best = imid
imin = imid + 1
} else {
imax = imid - 1
}
}
return best
}
func sortNSortedLists(in [][]int) []int {
var out []int
cursors := make([]int, len(in))
for {
// Find the array indices that have the smallest
// and next to smallest value (may be same) at
// their current cursor.
minIdx1 := -1
minIdx2 := -1
minVal1 := math.MaxInt32
minVal2 := math.MaxInt32
for i, cursor := range cursors {
if cursor >= len(in[i]) {
continue
}
if in[i][cursor] < minVal1 {
minIdx2 = minIdx1
minVal2 = minVal1
minIdx1 = i
minVal1 = in[i][cursor]
} else if in[i][cursor] < minVal2 {
minIdx2 = i
minVal2 = in[i][cursor]
}
}
if minIdx1 == -1 {
// no values
break
}
if minIdx2 == -1 {
// only one array has values, so append the
// remainder of it to output
out = append(out, in[minIdx1][cursors[minIdx1]:]...)
break
}
// If inVal1 is smaller than inVal2,
// append to output all values from minVal1 to minVal2 found in
// the minIdx1 array, and update the cursor for the minIdx1 array.
if minVal1 < minVal2 {
firstCursor := cursors[minIdx1]
lastCursor := findNext(in[minIdx1], firstCursor, minVal2)
if lastCursor != -1 {
out = append(out, in[minIdx1][firstCursor:lastCursor+1]...)
cursors[minIdx1] = lastCursor+1
continue
}
}
// Append the single value to output
out = append(out, minVal1)
cursors[minIdx1]++
}
return out
}
- 1. 將哈希錶轉換爲O(log(k)* k + n)中的排序數組
- 2. 計數排序O(n + k)時間複雜度是什麼k?
- 3. 算法的漸近分析:如何在時間O(k log k + n)中插入k個新元素到大小爲n的排序列表中
- 4. 排序大小爲k的problem- N/K的間隔的每個
- 5. 在k <n的算法運行時log(n)vs log(k)
- 6. 使用k次序統計的無序列表中的第K個元素 - 時間複雜度O(n)?
- 7. 算法複雜度,log^k n vs n log n
- 8. 排序在O(n + mlogm)時間陣列
- 9. 爲什麼排序字符串O(n log n)?
- 10. 快速排序中位數在O(n log n)
- 11. 合併大小爲n的k個排序數組的下界
- 12. 爲什麼合併排序最差情況運行時間O(n log n)?
- 13. O(N)查找,但O(日誌(N))的比較排序列表
- 14. 時間複雜度O(N日誌(log n)的)+ N O(L)
- 15. 排序在最壞情況下O(n * log(n))
- 16. python log n選擇k
- 17. 時間複雜度 - O(n^2)到O(n log n)搜索
- 18. 高效從n個選擇計算長度爲k的下一個排列
- 19. 通用實用的排序算法比O(n log n)快嗎?
- 20. 桶類的複雜度如何爲O(n + k)?
- 21. 在matlab中如何做(m,n,k)*(n,k)=(m,k)?
- 22. 打印k下一個按字典順序排列的n位數字排列
- 23. 返回列表[1,n,n^2,n^3,...,n^k]的函數powers(n,k),其中k是整數
- 24. 在O(log n)中查找第k個最小元素
- 25. 獲取k值的所有排列(k = 1 ... n)
- 26. 在O(n)時間的雙維數組排序排序
- 27. 從n個排序數組中找出k個最小數字
- 28. KSum如何最小運行時間爲O(N^k-1)?
- 29. 從[0..k]獲取整數值的n大小數組的排序和O(n)時間
- 30. 算法K-Way合併。這個解決方案是O(n log k)嗎?
得十分小心。 – 2010-03-20 03:43:54
你的意思是合併並排序n個排序列表,其平均長度K在O(n * log K)時間內? – 2010-03-20 03:48:42
是的你的權利布賴恩,我的意思是 – 2010-03-20 03:57:30