优先级队列其实就是堆排序的意思。
已知一个几乎有序的数组,几乎有序是指,如果把数组排好序的话,每个元素移动的距离不超过K,并且k相对于数组来说比较小。请选择一个合适排序算法针对这个数据进行排序。
分析:如果每个数组移动的距离不超过K,那么数组范围[0,k]内一定存在最小值,因为其他位置的值是不可能移动到数组0位置上的,同理[1,k+1]上存在第二小的值。
那么我们可以利用堆排序,小根堆。
先把[0,k]范围内的元素放到小跟堆中,取出根元素,那么就是这个数组中的最小值,然后再将k+1的元素加入到小根堆中,再取出根元素,就是这个数组中第二小的值。到没有元素可以加的时候,不断的将小根堆中的根元素拿出来就排好序了。
public static void sortedArrDistanceLessK(int[] arr,int k) {
//默认为小根堆,PriorityQueue就是优先级队列,也就是堆
PriorityQueue<Integer> heap = new PriorityQueue<Integer>();
int index = 0;
for(;index<Math.min(arr.length, k);index++) {
heap.add(arr[index]);
//将【0,k-1】的元素放进去
}
int i=0;
for(;index<arr.length;index++,i++) {
heap.add(arr[index]);//进一个元素就取出一个范围最小值。
arr[i] = heap.poll();
}
while(!heap.isEmpty()) {//最后剩余的元素全部以根元素的形式取出即可
arr[i++] = heap.poll();
}
}
系统给的堆排序只是说更加方便一点,但是只能做到给一个取出一个,要是需要更加复杂的操作的时候就需要手写堆排序了,但是本题中明显不需要。