最近有人问我这个面试问题:
您将得到一个几乎已排序的数组,因为每个
N
元素的错位可能不超过k
正确排序顺序的位置。寻找一种时空高效的算法对数组进行排序。
我有O(N log k)
如下解决方案。
让我们来表示arr[0..n)
从索引0
(包括)到N
(不包括)的数组元素。
- 分类
arr[0..2k)
- 现在我们知道
arr[0..k)
它们处于最终排序位置... - ...但是
arr[k..2k)
可能仍然被放错位置k
!
- 现在我们知道
- 分类
arr[k..3k)
- 现在我们知道
arr[k..2k)
它们处于最终排序位置... - ...但
arr[2k..3k)
可能仍会被k
- 现在我们知道
- 分类
arr[2k..4k)
- ....
- 直到您进行排序
arr[ik..N)
,然后您就完成了!- 当您
2k
剩余的元素少于时,此最后一步可能会比其他步骤便宜
- 当您
在每个步骤中,您最多要对中的2k
元素进行排序,请O(k log k)
至少k
在每个步骤的末尾将元素置于其最终排序位置。有O(N/k)
步骤,因此总体复杂度为O(N log k)
。
我的问题是:
- 是
O(N log k)
最优的吗?这可以改善吗? - 您能做到这一点而无需(部分)重新排序相同的元素吗?