写点什么

精选算法面试 - 优先队列

用户头像
李孟
关注
发布于: 2021 年 01 月 12 日
精选算法面试-优先队列

一.简介

Java 中 PriorityQueue 通过二叉小顶堆实现,可以用一棵完全二叉树表示。

二.示例

2.1 数据流中的第 K 大元素

设计一个找到数据流中第 k 大元素的类(class)。注意是排序后的第 k 大元素,不是第 k 个不同的元素。

示例

输入:["KthLargest", "add", "add", "add", "add", "add"][[3, [4, 5, 8, 2]], [3], [5], [10], [9], [4]]输出:[null, 4, 5, 5, 8, 8]解释:KthLargest kthLargest = new KthLargest(3, [4, 5, 8, 2]);kthLargest.add(3);   // return 4kthLargest.add(5);   // return 5kthLargest.add(10);  // return 5kthLargest.add(9);   // return 8kthLargest.add(4);   // return 8
复制代码


private PriorityQueue<Integer> queue;private int limit;public KthLargest(int k, int[] nums) {    queue = new PriorityQueue<>(k);    limit = k;    for(int n : nums){        add(n);    }}//固定的queue,添加元素public int add(int val) {    if(queue.size() < limit){        queue.add(val);    }else if(val > queue.peek()){        queue.poll();        queue.add(val);    }    return queue.peek();}
复制代码

2.2 滑动窗口最大值


给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。

返回滑动窗口中的最大值。


示例

输入:nums = [1,3,-1,-3,5,3,6,7], k = 3输出:[3,3,5,5,6,7]解释:滑动窗口的位置                最大值---------------               -----[1  3  -1] -3  5  3  6  7       31 [3  -1  -3] 5  3  6  7       31  3 [-1  -3  5] 3  6  7       51  3  -1 [-3  5  3] 6  7       51  3  -1  -3 [5  3  6] 7       61  3  -1  -3  5 [3  6  7]      7
复制代码

优先级队列实现

public int[] maxSlidingWindow(int[] nums, int k) {        int length = nums.length;        int[] res = new int[length - k + 1];        PriorityQueue<int[]> queue = new PriorityQueue<>(new Comparator<int[]>() {            @Override            public int compare(int[] o1, int[] o2) {                return o1[0] != o2[0] ? o2[0] - o1[0] : o2[1] - o1[1];            }        });        for (int i = 0; i < k; i++) {            queue.offer(new int[]{nums[i],i});        }        res[0] = queue.peek()[0];        //滑动窗口变大了 (k + k - 1) 运用大顶堆,找最大        for (int i = k; i < length; i++) {            queue.offer(new int[]{nums[i],i});            while (queue.peek()[1] <= (i-k)){                queue.poll();            }            res[i-k+1] = queue.peek()[0];        }        return res;}
复制代码

双端队列

public int[] maxSlidingWindow(int[] nums, int k) {        int n = nums.length;        Deque<Integer> deque = new LinkedList<Integer>();        for (int i = 0; i < k; ++i) {            while (!deque.isEmpty() && nums[i] >= nums[deque.peekLast()]) {                deque.pollLast();            }            deque.offerLast(i);        }        int[] ans = new int[n - k + 1];        ans[0] = nums[deque.peekFirst()];        for (int i = k; i < n; ++i) {            while (!deque.isEmpty() && nums[i] >= nums[deque.peekLast()]) {                deque.pollLast();            }            deque.offerLast(i);            while (deque.peekFirst() <= i - k) {                deque.pollFirst();            }            ans[i - k + 1] = nums[deque.peekFirst()];        }        return ans;    }
复制代码

参考

https://leetcode-cn.com/problems/sliding-window-maximum/

https://leetcode-cn.com/problems/kth-largest-element-in-a-stream/discuss/149050/Java-Priority-Queue/


发布于: 2021 年 01 月 12 日阅读数: 23
用户头像

李孟

关注

还未添加个人签名 2017.10.18 加入

数据工程师 https://limeng.blog.csdn.net/

评论

发布
暂无评论
精选算法面试-优先队列