【算法系列-栈与队列】队列的应用(前k高频元素 + 滑动窗口最大值)

【算法系列-栈与队列】队列的应用(前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;
    }
}

以上便是对一些队列应用相关问题的介绍了!!后续还会继续分享其它算法系列内容,如果这些内容对大家有帮助的话请给一个三连关注吧💕( •̀ ω •́ )✧( •̀ ω •́ )✧✨

相关推荐
椰羊~王小美43 分钟前
LeetCode -- Flora -- edit 2025-04-27
算法·leetcode·职场和发展
缘友一世2 小时前
从线性回归到逻辑回归
算法·逻辑回归·线性回归
前端_学习之路2 小时前
javaScript--数据结构和算法
javascript·数据结构·算法
weixin_428498493 小时前
使用HYPRE库并行装配IJ稀疏矩阵指南: 矩阵预分配和重复利用
算法·矩阵
雾削木5 小时前
mAh 与 Wh:电量单位的深度解析
开发语言·c++·单片机·嵌入式硬件·算法·电脑
__lost5 小时前
小球在摆线上下落的物理过程MATLAB代码
开发语言·算法·matlab
mit6.8246 小时前
[Lc_week] 447 | 155 | Q1 | hash | pair {}调用
算法·leetcode·哈希算法·散列表
jerry6097 小时前
优先队列、堆笔记(算法第四版)
java·笔记·算法
勤劳的牛马8 小时前
📚 小白学算法 | 每日一题 | 算法实战:加1!
算法
Epiphany.5568 小时前
基于c++的LCA倍增法实现
c++·算法·深度优先