单调队列
使用双端队列Dequ实现单调队列。
for循环遍历数组,每次往队尾加入一个数之前,先将队尾小于它的元素全部出队。这样可以保证队尾到队头是递增的。队头是当前最值。
单调队列不是一成不变的,而是不同场景不同写法,总之要保证队列里单调递减或递增的原则,所以叫做单调队列。
结合滑动窗口最大值题目。单调队列加入的元素是数组下标,用来判断窗口边界。每到一个新窗口,按照单调队列方法在队尾加入元素之后,还要处理队头元素,保证其在新窗口范围内。
for (int i = k; i < nums.length; i++) {
while (!deque.isEmpty() && nums[i] > nums[deque.peekLast()]) {
deque.pollLast();
}
deque.offer(i);
// make sure : window[i-k+1,i],
while (deque.peekFirst() < i - k + 1) deque.pollFirst();
res[count++] = nums[deque.peekFirst()];
}
优先队列
PriorityQueue(优先队列) 采用的是堆排序,实际上是一个堆(不指定Comparator时默认为最小堆),即升序,队头元素最小。 堆排序只能保证根是最大(最小),整个堆并不是有序的。
例子:
@Test
public void testPriorityQueue(){
//默认采用的是最小堆实现的
PriorityQueue<Integer> queue = new PriorityQueue<Integer>(new Comparator<Integer>(){
public int compare(Integer a, Integer b){
return a-b; //if a>b 则交换,升序
}
});
queue.offer(13);
queue.offer(9);
int len = queue.size();
for(int i=0;i<len;i++){
System.out.println(queue.poll());
}
//输出 9 13
}
- 自定义类型
public class PriorityQueueTest{
public static void main(String args[]){
PriorityQueue<People> queue = new PriorityQueue<People>(11,
new Comparator<People>() {
public int compare(People p1, People p2) {
return p2.age - p1.age;
}
});
for (int i = 1; i <= 10; i++) {
queue.add(new People("张"+ i, (new Random().nextInt(100))));
}
while (!queue.isEmpty()) {
System.out.println(queue.poll().toString());
}
}
}
class People {
String name;
int age;
public People(String name, int age){
this.name = name;
this.age = age;
}
public String toString() {
return "姓名:"+name + " 年龄:" + age;
}
}
优先队列遍历
PriorityQueue的iterator()不保证以任何特定顺序遍历队列元素。若想按特定顺序遍历,先将队列转成数组,然后排序遍历。
Object[] nn=q.toArray();
Arrays.sort(nn);