正如标题所示,我想知道合并k个大小为n的排序数组的下界的证明是什么?我知道界限是O(kn * log [k]),但是这是如何实现的?我试着比较使用决策树对p元素数组进行排序,但我不知道如何实现这个证明。合并大小为n的k个排序数组的下界
回答
这很容易证明,请尝试以合并排序的方式考虑它。
要合并排序大小为的数组,K * N需要O(KN * log(K * N))。
但是我们没有达到叶子大小的,因为我们知道,当数组大小ň将垃圾分类。为了简单起见,我们将假设K是2的幂。
我们必须用2除以多少次才能达到尺寸为N的叶子?
K次!
可视化
所以,你必须日志(k)的步骤,然后将具有合并的每个步骤成本ķÑ,并且有日志(k)的步骤。因此,时间复杂度为O(NK(日志(K))
证明:
让我们假设它不是一个下限,我们可以取得更好的那么对于大小的任何未知的数组ñ* K我们可以在2,直到我们达到尺寸ñ的子阵列它分割,合并排序的每个的大小为N的阵列的在NLOG(N)对于所有阵列K个时和在总* N * log(N) time。
在将K个大小为N的数组排序后,我们必须将它们合并成一个大小较大的数组,大小为N * K,支付小于O(NK *(log(K)),因为我们假设它不是下限。
最后,您在复杂度小于N * K * log(N * K)的情况下对大小为N * K的未知数组排序,这在比较模型中是不可能的。
因此,你无法实现优于O(NK *(日志(K))而合并K个排序的大小N的数组
可能的实现。
让我们创建一个储存对(element, arrayIndex)
一个heap data structure然后
- 将每个数组的第一个元素与相应的数组索引添加到这个堆中。
- 在每个步骤中,除去顶部(最低)对
p
从堆中,添加p.element
到的结果,并插入到堆的一对(next, p.arrayIndex)
与从阵列的下一个元素与p.arrayIndex
索引(如果非空) 。
为了跟踪'next'元素,你需要一个包含指向相应数组下一个元素的指数/指针/迭代器的数组。
将有在任何时间在堆至多k
元素,因此堆的insert
/remove
操作将有O(log(k))
复杂性。每个元素都将被插入并从堆中移除一次。元素的数量是n*k
。整体复杂度为O(n*k*log(k))
。
创建一个大小为k的小堆,存储来自每个k个阵列的下一个项目。每个节点还存储它来自哪个数组。通过将堆中的min添加到final_sorted_array来创建排序后的数组,然后添加数组中来自堆的下一个元素。
删除堆的最小值为O(log k)。你总共有NK元素,所以你做这个NK时代。最终结果:O(NK log k)。
- 1. 排序大小为k的problem- N/K的间隔的每个
- 2. 在大小为N的未排序数组中查找K个最小整数
- 3. 从n个排序数组中找出k个最小数字
- 4. 数组大小为n的形式为k = 2^n的键的查找表
- 5. 生成从整数矢量大小为k的下一个组合
- 6. 从[0..k]获取整数值的n大小数组的排序和O(n)时间
- 7. 将哈希表转换为O(log(k)* k + n)中的排序数组
- 8. 在Ruby中懒散地合并N个排序的数组
- 9. k个元素的全部组合n
- 10. 确定合并排序中边数组的大小
- 11. Tricky数学! Ñ大小K个阵列(总KXN),需要的大小为N的所有可能的排列
- 12. 对于每个k = 1的所有大小为k的子阵列的最大总和为n .. n
- 13. Scala函数获取大小为k的所有排序子集
- 14. 合并排序的数组
- 15. 从大小为K的对象组中生成所有大小为N的集合
- 16. 合并排序来排序n值数组
- 17. 获取大小为n的所有二进制组合,但只有k 1s
- 18. 一个N×M阵列或M个大小为N的数组?
- 19. 从n个组中查找所有组合的大小n
- 20. 查找n个排序元素的中间k组合的高效方法
- 21. 打印k下一个按字典顺序排列的n位数字排列
- 22. 如何将n个排序列表中的平均长度K排序为O(n * log K)时间?
- 23. 找到第k个最小的元素在联合的2排序的大小为m列表和n与效率日志(k)的
- 24. 查找未排序数组中的第k个最小元素
- 25. K路合并的最大K值
- 26. 随机从大小为n的数组
- 27. 大小为n的数组,其中一个元素n/2次
- 28. 如何证明\ Omega {(n(logn)^ k)}的下界? [k> 1]
- 29. 最优化的方式来组合n个大小为k的特殊组,以满足特定要求
- 30. 算法的渐近分析:如何在时间O(k log k + n)中插入k个新元素到大小为n的排序列表中