已知一个几乎有序的数组,把数组排好顺序的话,每个元素移动的距离一定不超过k,并且k相对于数组长度来说比较小
1.这道题如果我们不使用的k的条件,正常使用排序的算法,也是可以做的,只是复杂度过高,不是最优解;
2. 第一眼看到这个问题,感觉情况很多,有一种无从下手的感觉,其实从最简单情况,我们就会有一点思路,最简单的例子:前k+1个元素,我们一定可以确定第一个位置的元素,这是因为移动距离不超过k,当我们确定第一个位置,考虑从[1,k+1]一定可以确定第二个位置的元素,依次类推
3.我们使用小根堆这种数据结构最为容器承载k+1个元素,很方便的获取堆中的元素
public void kOrder(int[] array,int k) {
PriorityQueue<Integer> queue = new PriorityQueue<>();
// 前k+1个元素进行入优先级队列
//使用指针记录当前已经添加到优先级队列的位置
int right = 0,int min = Math.min(k+1,array.length);
while(right < min) {
queue.offer(array[right++]);
}
//curIndex 记录待排序的位置
int curIndex = 0;
while(!queue.isEmpty()) {
//弹出最小元素进行排序
array[curIndex++] = queue.poll();
if(right < array.length){
queue.offer(array[right++]);
}
}
}
第二种方式,对实现方式进行了微调
public void kOrder(int[] array,int k) {
PriorityQueue<Integer> queue = new PriorityQueue<>();
int min = Math.min(k+1,array.length);
int right = 0;
while(right < min){
queue.offer(array[right++]);
}
int curIndex = 0;
while(right < array.length){
this.array[curIndex++] = queue.poll();
queue.offer(this.array[right++]);
}
while(!queue.isEmpty()){
this.array[curIndex++] = queue.poll();
}
}