最近有人问我这个面试问题:
您将得到一个几乎已排序的数组,因为每个
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)最优的吗?这可以改善吗? - 您能做到这一点而无需(部分)重新排序相同的元素吗?