【算法系列-栈与队列】队列的应用(前k高频元素 + 滑动窗口最大值)
文章目录
- [【算法系列-栈与队列】队列的应用(前k高频元素 + 滑动窗口最大值)](#【算法系列-栈与队列】队列的应用(前k高频元素 + 滑动窗口最大值))
-
- [1. 滑动窗口最大值(LeetCode 239)](#1. 滑动窗口最大值(LeetCode 239))
-
- [1.1 思路分析🎯](#1.1 思路分析🎯)
- [1.2 解题过程🎬](#1.2 解题过程🎬)
- [1.3 代码示例🌰](#1.3 代码示例🌰)
- [2. 前k个高频元素(LeetCode 347)](#2. 前k个高频元素(LeetCode 347))
-
- [2.1 思路分析🎯](#2.1 思路分析🎯)
- [2.2 代码示例🌰](#2.2 代码示例🌰)
1. 滑动窗口最大值(LeetCode 239)
【题目链接】239. 滑动窗口最大值 - 力扣(LeetCode)
1.1 思路分析🎯
这道题使用单调队列的方式解决
Dequeue(双端队列) + 自定义队列 -> 形成单调队列
这里我们维护一个队列:
队列出口处的数值保证是当前窗口下的最大值;
每次往队列添加元素,先将排在当前元素之前且比当前元素小的数都从队列中弹出,再将元素添加进队列中;
每次从队列弹出元素,得当元素等于队列出口元素时才可弹出,否则无需操作队列
1.2 解题过程🎬
初始化上述定义的队列,先将前k个元素添加到队列中,添加时队列会进行判断,最后留在出口位置的是当前窗口中的最大值;之后从 下标k 开始进行窗口移动,取队列出口值添加进返回数组;
直到nums数组遍历完,返回结果数组
1.3 代码示例🌰
java
class Solution {
class MyQueue {
Deque<Integer> queue = new LinkedList<>();
void poll(int val) {
// 当元素等于队列出口元素时才可弹出,否则无需操作队列
if (!queue.isEmpty() && queue.peek() == val) {
queue.poll();
}
}
void add(int val) {
// 每次往队列添加元素,先将排在当前元素之前且比当前元素小的数都从队列中弹出,再将元素添加进队列中
while (!queue.isEmpty() && val > queue.getLast()) {
queue.removeLast(); // 双端队列Dequeue可以从后弹出元素
}
queue.add(val);
}
// 队列出口处维护的就是最大值
int peek() {
return queue.peek();
}
}
public int[] maxSlidingWindow(int[] nums, int k) {
MyQueue queue = new MyQueue();
int[] ret = new int[nums.length - k + 1];
for (int i = 0;i < k;i++) {
queue.add(nums[i]);
}
int len = 0;
ret[len++] = queue.peek();
// i = k,开始窗口移动
for (int i = k;i < nums.length;i++) {
queue.poll(nums[i - k]);
queue.add(nums[i]);
ret[len++] = queue.peek();
}
return ret;
}
}
2. 前k个高频元素(LeetCode 347)
【题目链接】347. 前 K 个高频元素 - 力扣(LeetCode)
2.1 思路分析🎯
map映射 + 优先级队列
通过map来记录每个元素出现的频率,之后使用优先级队列 (这里使用小根堆,即父元素小于左右子元素,最小的元素在堆顶),通过遍历将每个map元素转换成数组并都添加进队列中,且当队列元素大于k时,将堆顶元素弹出(最小值),从而保证队列中只存在k个元素,最后弹出队列中的每个元素并取0下标值(原map的key),赋值给返回数组
2.2 代码示例🌰
java
class Solution {
public int[] topKFrequent(int[] nums, int k) {
Map<Integer, Integer> map = new HashMap<>();
PriorityQueue<int[]> queue = new PriorityQueue<>((n1, n2) -> n1[1] - n2[1]);
for (int x : nums) {
map.put(x, map.getOrDefault(x, 0) + 1);
}
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
int[] temp = new int[2];
temp[0] = entry.getKey();
temp[1] = entry.getValue();
queue.offer(temp);
if (queue.size() > k) {
queue.poll();
}
}
int[] ret = new int[k];
for (int i = 0;i < k;i++) {
ret[i] = queue.poll()[0];
}
return ret;
}
}
以上便是对一些队列应用相关问题的介绍了!!后续还会继续分享其它算法系列内容,如果这些内容对大家有帮助的话请给一个三连关注吧💕( •̀ ω •́ )✧( •̀ ω •́ )✧✨