我看到了以下问题。
给定一个包含n个元素和一个整数k,其中k<n。已经排好序的元素{a0...ak}和 {ak+1...an}。请提供一种时间复杂度为O(n),空间复杂度为O(1)的算法进行排序。
在我看来,似乎无法以O(n)时间复杂度和O(1)空间复杂度完成此任务。实际上,这个问题似乎是在询问如何在原地执行归并排序中的合并步骤。如果可以这样做,为什么不将归并排序实现为这种方式呢?然而,我还没有完全相信自己的判断,需要一些意见。
我看到了以下问题。
给定一个包含n个元素和一个整数k,其中k<n。已经排好序的元素{a0...ak}和 {ak+1...an}。请提供一种时间复杂度为O(n),空间复杂度为O(1)的算法进行排序。
在我看来,似乎无法以O(n)时间复杂度和O(1)空间复杂度完成此任务。实际上,这个问题似乎是在询问如何在原地执行归并排序中的合并步骤。如果可以这样做,为什么不将归并排序实现为这种方式呢?然而,我还没有完全相信自己的判断,需要一些意见。
这篇文章似乎表明可以用O(lg^2 n)空间完成。我无法证明在常数空间内合并不可能,但我也不知道如何做到。
编辑: 查找参考资料,Knuth Vol 3 - Exercise 5.5.3说:“L. Trabb-Pardo的一种更为复杂的算法为这个问题提供了最佳答案:可以使用固定数量的索引变量,仅使用O(lg n)比特的辅助存储器,在O(n)时间内完成稳定合并和O(n lg n)时间内完成稳定排序。”
还有其他参考资料我没有阅读。感谢提供有趣的问题。
进一步编辑: 这篇文章声称,黄先生和兰斯顿先生的算法可以在O(m + n)的时间内合并两个大小为m和n的列表,所以你的问题的答案似乎是肯定的。不幸的是,我没有这篇文章的访问权限,所以我必须相信二手信息。我不确定如何将其与Knuth的声明相一致,即Trabb-Pardo算法是最优的。如果我的生命取决于此,我会选择Knuth。不可能的,如果可以的话,我的工作会容易得多 :)
你有一个无法避免的O(log n)因素。你可以选择将其作为时间或空间,但唯一避免它的方法是不排序。使用O(log n)空间,您可以构建一个连续列表,跟踪未完全适合的元素的存储位置。通过递归,这可以使其适合于O(1)堆,但这只是使用O(log n)堆栈帧实现的。
以下是从1-9合并奇数和偶数的进度。请注意,您需要对记录由常量空间和线性交换的双重约束引起的顺序反转进行对数空间记账。
. - 135792468 . - 135792468 : .- 125793468 : .- 123795468 #.:- 123495768 :.- 123459768 .:- 123456798 .- 123456789
123456789
有一些微妙的边界条件,比二分查找更难正确处理,即使在这种(可能)形式下,也是一个糟糕的家庭作业问题;但是这是一个非常好的头脑锻炼。
更新 显然我错了,存在一种算法可以在O(n)时间和O(1)空间内实现。我已经下载了相关论文来让自己更清楚,因此撤回这个错误的答案。