http://www.cnblogs.com/jack204/archive/2012/10/10/2717795.html
已知一个n个元素的数组,第i个元素在排序后的位置在[i-k,i+k]区间,k<<n .让你设计一个算法对数组排序,要求时间复杂度最小
方法1:
建一个k的小堆,每次取最小,插入下一个,维护这个堆n次,总共为O(nlogk)。
归纳法证明:
1 前k个取出最小的必然就是全部数组的最小的,因为第一个位置的在[0, k-1]之中的一个。
2 第j个取出来的数字,在数组就在j的位置上。因为根据题意,第j个大的必然在(j-k, j+k)之间。他必然在[0, j+k-1]中第j个大的,前面已经有[0, j-1]了,所以从堆中取出来就是第j个大的。即在数组的第j个位置上。
方法2:
a[i]在排序后的位置是[i-k, i+k],a[i+2k]在排序后的位置是[i+k, i+3k],必然有a[i] <= a[i+2k],所以数组a里实际上有2k个各自有序的、交错的子序列,如a1={a[0], a[2k], a[4k]...},a2={a[1], a[2k+1], a[4k+1], ...}
所以可以用2k-路归并排序,用一个大小为2k的小顶堆辅助归并,时间复杂度是O(n*log2k)
6917

被折叠的 条评论
为什么被折叠?



