javaPirorityQueue

在介绍 ArrayDeque 类之前,可以从上图中看出,ArrayDeque 实现了 Deque 接口,Deque 是啥呢,全称含义为double ended queue,即双端队列。Deque 接口的实现类可以被当作 FIFO(队列)使用,也可以当作 LIFO(栈)来使用。

其中队列(FIFO)表示先进先出,比如水管,先进去的水先出来;栈(LIFO)表示先进后出,比如,手枪弹夹,最后进去的子弹,最先出来。

ArrayDeque 是 Deque 接口的一种具体实现,所以,既可以当成队列,也可以当成栈来使用,

参考资料:
just-do java

ArrayDeque 和 LinkedList 都是 Deque 接口的实现类,都具备既可以作为队列,又可以作为栈来使用的特性,两者主要区别在于底层数据结构的不同。

ArrayDeque 底层数据结构是以循环数组为基础,而 LinkedList 底层数据结构是以循环链表为基础。理论上,链表在添加、删除方面性能高于数组结构,在查询方面数组结构性能高于链表结构,但是对于数组结构,如果不进行数组移动,在添加方面效率也很高。

img

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;

    }
}
posted @ 2023-02-13 08:47  Indullged  阅读(44)  评论(0编辑  收藏  举报