javaPirorityQueue
在介绍 ArrayDeque 类之前,可以从上图中看出,ArrayDeque 实现了 Deque 接口,Deque 是啥呢,全称含义为double ended queue,即双端队列。Deque 接口的实现类可以被当作 FIFO(队列)使用,也可以当作 LIFO(栈)来使用。
其中队列(FIFO)表示先进先出,比如水管,先进去的水先出来;栈(LIFO)表示先进后出,比如,手枪弹夹,最后进去的子弹,最先出来。
ArrayDeque 是 Deque 接口的一种具体实现,所以,既可以当成队列,也可以当成栈来使用,
参考资料:
just-do java
ArrayDeque 和 LinkedList 都是 Deque 接口的实现类,都具备既可以作为队列,又可以作为栈来使用的特性,两者主要区别在于底层数据结构的不同。
ArrayDeque 底层数据结构是以循环数组为基础,而 LinkedList 底层数据结构是以循环链表为基础。理论上,链表在添加、删除方面性能高于数组结构,在查询方面数组结构性能高于链表结构,但是对于数组结构,如果不进行数组移动,在添加方面效率也很高。
Java优先队列
优先队列的作用是能保证每次取出的元素都是队列中权值最小的(Java的优先队列每次取最小元素,C++的优先队列每次取最大元素)。这里牵涉到了大小关系,元素大小的评判可以通过元素本身的自然顺序(natural ordering),也可以通过构造时传入的比较器(Comparator,类似于C++的仿函数)。Java中PriorityQueue实现了Queue接口,不允许放入null元素;
Java最大堆API:可使用优先队列来实现最大堆。需要设置比较器为逆序:
Queue<Integer> maxHeap = new PriorityQueue<>(Comparator.reverseOrder());
PriorityQueue:默认是最小堆 ,需要设置过之后,才能成为最大堆。
优先队列的方法有:
将元素插入PriorityQueue
add() - 将指定的元素插入队列。如果队列已满,则会引发异常。
offer() - 将指定的元素插入队列。如果队列已满,则返回false。
访问PriorityQueue元素
要从优先级队列访问元素,我们可以使用peek()方法。此方法返回队列的头部。
删除PriorityQueue元素
remove() - 从队列中删除指定的元素
poll() - 返回并删除队列的开头
遍历:
import java.util.PriorityQueue;
import java.util.Iterator;
class Main {
public static void main(String[] args) {
//创建优先级队列
PriorityQueue<Integer> numbers = new PriorityQueue<>();
numbers.add(4);
numbers.add(2);
numbers.add(1);
System.out.print("使用iterator()遍历PriorityQueue : ");
//使用iterator()方法
Iterator<Integer> iterate = numbers.iterator();
while(iterate.hasNext()) {
System.out.print(iterate.next());
System.out.print(", ");
}
}
}
contains(element) 在优先级队列中搜索指定的元素。如果找到该元素,则返回true,否则返回false。
size() 返回优先级队列的长度。
toArray() 将优先级队列转换为数组,并返回它。
力扣习题:
输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。
示例 1:
输入:arr = [3,2,1], k = 2
输出:[1,2] 或者 [2,1]
示例 2:
输入:arr = [0,1,2,1], k = 1
输出:[0]
使用堆数据结构来辅助得到最小的 k 个数。堆的性质是每次可以找出最大或最小的元素。我们可以使用一个大小为 k 的最大堆(大顶堆),将数组中的元素依次入堆,当堆的大小超过 k 时,便将多出的元素从堆顶弹出。
class Solution {
public int[] getLeastNumbers(int[] arr, int k) {
if (k==0)
return new int[0];
//最大堆,相当于维护一个k容量的栈,堆顶就是最大值
Queue<Integer> heap = new PriorityQueue<>(Comparator.reverseOrder());
for (int i : arr) {
if (heap.isEmpty() || heap.size() <k || i<heap.peek()){
heap.offer(i);
}
if (heap.size()>k){
heap.poll();
}
}
int[] res = new int[heap.size()];
for (int i = 0; i < res.length; i++) {
res[i]=heap.poll();
}
return res;
}
}