代码随想录27期|Python|Day13|栈与队列|239. 滑动窗口最大值 (一刷至少需要理解思路)|347.前 K 个高频元素 (一刷至少需要理解思路)

news/2024/7/7 21:41:57

239. 滑动窗口最大值

单调队列

滑动窗口中的队列一直保持出口大,入口小的顺序。(图:代码随想录)

1、每次有新的元素进入(也就是滑动窗口移动后),都需要先和入口的元素比较大小,如果大,就从队尾pop出之前的元素(双向队列的特性),如果小,则保留。

2、每次需要pop队列头部的元素,需要先和当前队列的头部元素比较,只pop滑动窗口即将舍弃的值

from collections import deque

class MyQueue:
    """
    双向队列dequeue
    始终保持队列头部pop()为最大值,尾部push()为最小值
    pop<-- [0] [1] [-1] <--push
            max mid min
    """
    def __init__(self):
        self.queue = deque()
    
    def pop(self, value):
        # 如果队列非空而且需要pop的值恰好就是队头的数值
        if self.queue and value == self.queue[0]:
            self.queue.popleft()

    def push(self, value):
        # 如果队列非空,而且需要push进入的值比队尾的值都大,那么队尾就一直pop出去
        while self.queue and value > self.queue[-1]:
            self.queue.pop()
        self.queue.append(value)
    
    def getMax(self):
        # 始终保持头部是最大值,返回队列头部就是最大值
        return self.queue[0]

class Solution(object):
    def maxSlidingWindow(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: List[int]
        """
        queue = MyQueue()
        ans = []
        # 先储存前k个数值,保证队列非空
        for i in range(k):
            queue.push(nums[i])
        ans.append(queue.getMax())
        # 然后遍历nums数组
        for i in range(k, len(nums)):
            queue.pop(nums[i - k])
            queue.push(nums[i])
            ans.append(queue.getMax())
        return ans

347. 前 K 个高频元素​​​​​​​

大顶堆:根节点是最大值,先pop的是最大值

小顶堆:根节点是最小值,先pop的是最小值

所以只需要按照出现频率排序放入小顶堆,然后pop直到还剩k个元素,再按照倒序输出即可。

优先级队列法

1、首先遍历数组建立map键值对;

2、建立小顶堆,按照从大到小的顺序放入键值对,当队列的长度大于k的时候,开始从最小值节点pop元素,留下k个最大值;

3、倒序输出最大值对应的key即可。

class Solution(object):
    def topKFrequent(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: List[int]
        """
        # 获取键值对
        map_freq = {}  # (key, value) = ('a', 4), ('b', 3) ...
        for item in nums:
            map_freq[item] = map_freq.get(item, 0) + 1  # 注意get写法
        
        # 构造小顶堆
        prime_que = []  # 创建优先级队列(这里是小顶堆)
        """
        heapq用法:
        heapq.heappush()是往堆中添加新值
        heapq.heappop()是从堆的根节点弹出值,大顶堆弹出最大值,小顶堆弹出最小值
        """
        for key, value in map_freq.items():
            heapq.heappush(prime_que, (value, key))  # 先入的是最大值
            if len(prime_que) > k:
                heapq.heappop(prime_que)
        res = [0] * k
        
        # 倒序输出
        for i in range(k-1, -1, -1):
            res[i] = heapq.heappop(prime_que)[1]
        return res

注意构造小顶堆的方式:heapq

heapq用法:

heapq.heappush()是往堆中添加新值

heapq.heappop()是从堆的根节点弹出值,大顶堆弹出最大值,小顶堆弹出最小值

 第13天完结🎉


http://lihuaxi.xjx100.cn/news/1885179.html

相关文章

运筹学经典问题(二):最短路问题

问题描述 给定一个图&#xff08;有向图或无向图&#xff09; G ( V , E ) G (V, E) G(V,E)&#xff0c; V V V是图中点的集合&#xff0c; E E E是图中边的集合&#xff0c;图中每条边 ( i , j ) ∈ E (i, j) \in E (i,j)∈E都对应一个权重 c i j c_{ij} cij​&#xff08;…

Altman作了多少恶?排挤首席科学家出GPT5开发、离间董事会、PUA员工

在山姆奥特曼&#xff08;Sam Altman&#xff09;被OpenAI董事会突然解职后的几天里&#xff0c;这个消息在科技圈引发轰动&#xff0c;该公司内部员工和许多科技界人士甚至将此举比作一场政变。 奥特曼被解雇后立即传出的说法是&#xff0c;OpenAI的广大员工都很喜欢他&#x…

系统日志分析

文章目录 系统日志分析1. Windows系统日志分析1.1 日志位置1.1.1 系统日志 System.evtx1.1.2 应用程序日志 Application.evtx1.1.3 安全日志 Security.evtx 1.2 打开日志审计策略功能1.3 查看系统日志1.4 事件日志分析1.4.1 日志清除记录——ID&#xff1a;11021.4.2 出站入站记…

深度解读:微信自动查券返利机器人的工作原理与实现思路

深度解读&#xff1a;微信自动查券返利机器人的工作原理与实现思路 大家好&#xff0c;我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;在当今的数字化时代&#xff0c;网络购物已经成为…

Ubuntu设置kubelet启动脚本关闭swap分区

查看swap分区 swapon -s打开swap分区 swapon -a查看/etc/fstab下所有固化的swap分区&#xff0c;注释 vi /etc/fstab修改kubelet.conf文件 vi /etc/systemd/system/kubelet.service.d/10-kubeadm.conf添加 ExecStartPre/sbin/swapoff -a生效 systemctl daemon-reload sys…

Dark Reader 浏览器自定义调节护眼模式的安装使用教程

Dark Reader 这是一个护眼扩展程序&#xff0c;通过实时生成黑暗主题&#xff0c;为每一个网站启用夜间模式。 Dark Reader 反转明亮的颜色&#xff0c;使网页内容具有高对比度并易于在夜间阅读。 Edge浏览器安装教程 1.获取附件及查看Google安装教程 可查看文章 Dark Reade…

(C++)vector介绍及其使用

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 前言 我们参考cplusplus文档逐个进行解释。 构造函数 push_back&&pop_back vector迭代器的使用 vector空间增长问题 我们发现resize不缩容&#xff0c;当然&#xff0c;这要看编译器的实现&#xff0c;不同的编译…

四十五----组件库设计

组件库设计主要考虑几点。 有意义: 命名准确,充分表意。参数准确,必要的类型检查。适当的注释 通用性:不要耦合特殊的业务功能。不要包含特定的代码处理逻辑。 ⽆状态,⽆副作⽤:状态向上层提取,尽量少⽤内部状态。解耦IO操作。 避免过度封装:合理冗余。避免过度抽象。 …