最近有人问我这样一个面试问题:
您得到一个几乎排序好的数组,因为每个
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)
中的大多数 2k
元素进行排序,在每个步骤结束时至少将 k
元素放在它们的最终排序位置。有 O(N/k)
步骤,所以总体复杂度是 O(N log k)
。
我的问题是:
O(N log k)
是最佳的吗? 这个可以改进吗?