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

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

相关推荐
Swift社区1 小时前
LeetCode - #139 单词拆分
算法·leetcode·职场和发展
Kent_J_Truman2 小时前
greater<>() 、less<>()及运算符 < 重载在排序和堆中的使用
算法
IT 青年2 小时前
数据结构 (1)基本概念和术语
数据结构·算法
Dong雨3 小时前
力扣hot100-->栈/单调栈
算法·leetcode·职场和发展
SoraLuna3 小时前
「Mac玩转仓颉内测版24」基础篇4 - 浮点类型详解
开发语言·算法·macos·cangjie
liujjjiyun3 小时前
小R的随机播放顺序
数据结构·c++·算法
¥ 多多¥4 小时前
c++中mystring运算符重载
开发语言·c++·算法
trueEve4 小时前
SQL,力扣题目1369,获取最近第二次的活动
算法·leetcode·职场和发展
天若有情6734 小时前
c++框架设计展示---提高开发效率!
java·c++·算法
ahadee5 小时前
蓝桥杯每日真题 - 第19天
c语言·vscode·算法·蓝桥杯