leetcode刷题-栈与队列03

news2024/10/6 10:30:24

代码随想录栈与队列part02|239. 滑动窗口最大值、347.前 K 个高频元素、总结

    • 239. 滑动窗口最大值
    • 347.前 K 个高频元素
    • 栈与队列总结

239. 滑动窗口最大值

leetcode题目链接
代码随想录文档讲解

思路
滑动窗口的移动过程很像一个队列(先进先出),滑动窗口向后移动一位,队列pop掉前面元素,push进去一个元素,调用get_max_value函数。

优先级队列:大顶堆、小顶堆(C++),但是优先级队列会把元素顺序改变,不能使用

单调队列:相对于优先级队列,单调队列可实现单调递增或单调递减,但如何加元素和如何将元素pop出来的规则是由我们自定义的。
没有必要将3个元素都加进来,只需要维护有可能成为最大值的放在出口。如果出口处有比当前最大值小的元素,pop。push的规则:每push一个元素,要pop一个元素,但是那个元素可能已经被pop掉了,(当队列中的元素>滑动窗口大小,pop);如果push进来的元素比前面的元素都大,那前面的元素都要pop掉,保证最大元素在出口出。

伪代码c++
注意: 判断时是top,之后是pop

// 自定义队列
deque<int>  que;
pop(int val){
	if( ! que.empty() && val == que.fornt()) // 如果要pop的元素是队列出口处的元素,说明左边要遗弃的元素是最大值
		que.pop_front(); //这是一个双向队列
}

push(int val){
	if( ! que.empty() && cal > que.back())  // 加入的元素比队列中元素大,把队列中小的元素都pop
		que.pop_back();
	que.push_back(val);
}
get_max_value()
	return que.front();

python代码

from collections import deque


class MyQueue: #单调队列(从大到小
    def __init__(self):
        self.queue = deque() #这里需要使用deque实现单调队列,直接使用list会超时
    
    #每次弹出的时候,比较当前要弹出的数值是否等于队列出口元素的数值,如果相等则弹出。
    #同时pop之前判断队列当前是否为空。
    def pop(self, value):
        if self.queue and value == self.queue[0]:
            self.queue.popleft()#list.pop()时间复杂度为O(n),这里需要使用collections.deque()
            
    #如果push的数值大于入口元素的数值,那么就将队列后端的数值弹出,直到push的数值小于等于队列入口元素的数值为止。
    #这样就保持了队列里的数值是单调从大到小的了。
    def push(self, value):
        while self.queue and value > self.queue[-1]:
            self.queue.pop()
        self.queue.append(value)
        
    #查询当前队列里的最大值 直接返回队列前端也就是front就可以了。
    def front(self):
        return self.queue[0]
    
class Solution:
    def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
        que = MyQueue()
        result = []
        for i in range(k): #先将前k的元素放进队列
            que.push(nums[i])
        result.append(que.front()) #result 记录前k的元素的最大值
        for i in range(k, len(nums)):
            que.pop(nums[i - k]) #滑动窗口移除最前面元素
            que.push(nums[i]) #滑动窗口前加入最后面的元素
            result.append(que.front()) #记录对应的最大值
        return result

347.前 K 个高频元素

leetcode题目链接
代码随想录文档讲解

思路

两个难点:

  1. 如何求每个数值出现的频率
  2. 如何对频率进行排序并求前k个高频元素
    -> map数据结构,时间复杂度高
    这里采用大顶堆和小顶堆(堆:二叉树)

遍历过后,堆里面只维护k个元素
选用小顶堆,因为在push进一个元素时,要先pop一个元素,在堆数据结构中,从堆顶开始pop,若采用大顶堆,每次都把频率最高的元素pop掉了。
在这里插入图片描述

伪代码(C++)

for(i=0; i< nums.size; i++)
	map[nums[i]]++;
// C++中可使用现成的数据结构,小顶堆的优先级队列
prioriy_queue<key,value>
cmp; //自定义排序代码
for(map:it){
	que.push(it);
	if(que.size>k)  que.pop();
}
vector<int> result
for(i=k-1; i>=0; i--){
	result[i] = que.top().first() // first获得元素
	que.pop()
}

python代码

Python中heapq模块
heappush(heap,item)建立大、小根堆
heapq.heappush()是往堆中添加新值,此时自动建立了小根堆
heapq.heappop(heap)
从 堆 弹出并返回最小的项目,保持堆不变。 如果堆为空,则会引发 IndexError。 要访问最小的项目而不弹出它,请使用 heap[0]。

代码示例
>>> a=[3,6,1]
>>> heapify(a)                  #将a变成堆之后,可以对其操作 heapq.heapfy()是以线性时间讲一个列表转化为小根堆
>>> heappop(a)
1
>>> b=[4,2,5]                   #b不是堆,如果对其进行操作,显示结果如下
>>> heappop(b)                  #按照顺序,删除第一个数值并返回,不会从中挑选出最小的
4
>>> heapify(b)                  #变成堆之后,再操作
>>> heappop(b)
2

#时间复杂度:O(nlogk)
#空间复杂度:O(n)
import heapq
class Solution:
    def topKFrequent(self, nums: List[int], k: int) -> List[int]:
        #要统计元素出现频率
        map_ = {} #nums[i]:对应出现的次数
        for i in range(len(nums)):
            map_[nums[i]] = map_.get(nums[i], 0) + 1
        
        #对频率排序
        #定义一个小顶堆,大小为k
        pri_que = [] #小顶堆
        
        #用固定大小为k的小顶堆,扫描所有频率的数值
        for key, freq in map_.items():
            heapq.heappush(pri_que, (freq, key))
            if len(pri_que) > k: #如果堆的大小大于了K,则队列弹出,保证堆的大小一直为k
                heapq.heappop(pri_que)
        
        #找出前K个高频元素,因为小顶堆先弹出的是最小的,所以倒序来输出到数组
        result = [0] * k
        for i in range(k-1, -1, -1):
            result[i] = heapq.heappop(pri_que)[1]
        return result
# 解法二
class Solution:
    def topKFrequent(self, nums: List[int], k: int) -> List[int]:
        # 使用字典统计数字出现次数
        time_dict = defaultdict(int)
        for num in nums:
            time_dict[num] += 1
        # 更改字典,key为出现次数,value为相应的数字的集合
        index_dict = defaultdict(list)
        for key in time_dict:
            index_dict[time_dict[key]].append(key)
        # 排序
        key = list(index_dict.keys())
        key.sort()
        result = []
        cnt = 0
        # 获取前k项
        while key and cnt != k:
            result += index_dict[key[-1]]
            cnt += len(index_dict[key[-1]])
            key.pop()

        return result[0: k]

栈与队列总结

  1. 栈与队列的底层实现
  2. 栈经典题目
    括号匹配、字符串去重、逆波兰表达式
  3. 队列经典题目
    滑动窗口最大问题、求前K个高频元素
  4. 通过求滑动窗口最大值,以及前K个高频元素介绍了两种队列:单调队列和优先级队列,这是特殊场景解决问题的利器,是一定要掌握的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1800457.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

『大模型笔记』Transformer系列技术博文汇总!

Transformer系列技术博文汇总&#xff01; 文章目录 第1篇&#xff1a;矩阵乘法概念解释第2篇&#xff1a;使用缩放点积方法的自注意力第3篇&#xff1a;深入探讨多头注意力、自注意力和交叉注意力第4篇&#xff1a;Transformer 架构第5篇&#xff1a;PostLN&#xff0c;PreLN…

Linux存储管理

简介 硬件上的存储设备目前有两类&#xff0c;通过磁头读写信息的机械硬盘和用主控芯片将信息写入晶体管的固态硬盘&#xff0c;硬盘调度算法等知识可以通过前面的操作系统设备管理文章学习&#xff0c;本章只介绍Linux中能对存储设备的操作。 为了让操作系统识别和管理物理磁…

企业差旅费管理如何实现真正的降本增效

看企业发展&#xff0c;不能只看当下&#xff0c;尤其对于看重长期价值的企业家来说&#xff0c;必须要用更长远的目光去看行业的未来。开源节流&#xff0c;扔掉一些没用的包袱减少负担&#xff0c;然后轻装上阵&#xff0c;并寻找企业发展的新增长点&#xff0c;仍然是众多企…

探索未来制造,BFT Robotics引领潮流

“买机器人&#xff0c;上BFT” 在这个快速变化的时代&#xff0c;创新和效率是企业发展的关键。BFT Robotics&#xff0c;作为您值得信赖的合作伙伴&#xff0c;专注于为您提供一站式的机器人采购和自动化解决方案。 产品系列&#xff1a; 协作机器人&#xff1a;安全、灵活、…

Vue3_对接腾讯云COS_大文件分片上传和下载

目录 一、腾讯云后台配置 二、安装SDK 1.script 引入方式 2.webpack 引入方式 三、文件上传 1.new COS 实例 2.上传文件 四、文件下载 腾讯云官方文档&#xff1a; 腾讯云官方文档https://cloud.tencent.com/document/product/436/11459 一、腾讯云后台配置 1.登录 对…

【外汇天眼】选择外汇EA的关键:策略适配、风险控制与稳定性评估

外汇EA&#xff08;Expert Advisor&#xff09;是外汇交易市场中广泛使用的自动化交易系统。它们通过预定义的规则和算法自动执行交易&#xff0c;旨在为交易者提供便捷的交易体验&#xff0c;同时提高交易效率和准确性。本文将从策略选择、风险控制和稳定性评估三个方面&#…

OKP绩效管理系统:助力企业实现卓越绩效

在当今竞争激烈的商业环境中&#xff0c;绩效管理系统成为企业提升效率和竞争力的重要工具。搭贝OKP绩效管理系统通过其强大的功能模块&#xff0c;帮助企业全面优化绩效管理流程&#xff0c;提升员工工作效率和企业整体绩效。本文将详细介绍搭贝OKP绩效管理系统的核心功能模块…

SpringBoot中的WebMvcConfigurationSupport和WebMvcConfigurer

在SpringBoot中可以通过以下两种方式来完成自定义WebMvc的配置&#xff1a; &#xff08;1&#xff09;继承WebMvcConfigurationSupport类 &#xff08;2&#xff09;实现WebMvcConfigurer接口 通过这两种方式完成的WebMvc配置存在差异&#xff0c;本文将对此作简单说明与区…

官网万词霸屏推广 轻松实现百度万词霸屏源码系统 带完整的安装代码包以及搭建教程

系统概述 官网万词霸屏推广源码系统是一款基于先进技术研发的综合性 SEO 工具。它的设计理念是通过智能化的算法和策略&#xff0c;帮助用户快速提升网站在百度等搜索引擎中的排名&#xff0c;实现大量关键词的霸屏效果。该系统整合了多种优化技术&#xff0c;包括关键词研究、…

日本指数实时API接口

日本 指数 实时API接口 # Restful API https://tsanghi.com/api/fin/index/JPN/realtime?token{token}&ticker{ticker}指定指数代码&#xff0c;获取该指数的实时行情&#xff08;开、高、低、收、量&#xff09;。 更新周期&#xff1a;实时。 请求方式&#xff1a;GET。…

Kali linux学习入门

Kali linux学习入门 文章目录 Kali linux学习入门Kali Linux简介Kali Linux工具篇Kali Docker安装Docker 更换国内镜像源Kali 安装 docker compose Kali Linux文档篇Kali Linux 社区篇 Kali Linux简介 Kali Linux是专门用于渗透测试linux操作系统&#xff0c;它由BackTrack发展…

Bev 车道标注方案及复杂车道线解决

文章目录 1. 数据采集方案1.1 传感器方案1.2 数据同步2. 标注方案2.1 标注注意项2.2 4d 标注(时序)2.2.1 4d标签制作2.2.2 时序融合的作用2.2.2.1 时序融合方式2.2.2.2 时序融合难点2.2.2.2 时序实际应用情况3. 复杂车道线解决3.1 split 和merge车道线的解决3.2 大曲率或U形车道…

单列集合.java

单列集合 为了存储不同类型的多个对象&#xff0c;Java提供了一些特殊系列的类&#xff0c;这些类可以存储任意类型的对象&#xff0c;并且存储的长度可变&#xff0c;这些类统称为集合。可以简单的理解为一个长度可变&#xff0c;可以存储不同数据类型的动态数组。集合都位于j…

mysql的binlog占用大量磁盘空间的解决方法

查看当前日志保存天数&#xff1a; mysql> show variables like %expire_logs_days%; ------------------------- | Variable_name | Value | ------------------------- | expire_logs_days | 0 | ------------------------- 1 row in set (0.08 sec) 默认是0&…

Mac - Node/Java 配置安装全流程

Mac - Node/Java 配置安装全流程 一. Git 安装二. Java 相关安装2.1 jenv 版本控制工具2.2 JDK1.8 和 JDK21的安装2.3 maven 安装 三. Node 相关安装3.1 nvm 版本控制工具3.2 Node 版本安装 一. Git 安装 1.我们首先安装一下Homebrew&#xff0c;这个工具很有用&#xff0c;能…

大数据处理学习笔记

sudo tar -zxvf hadoop-1.1.2.tar.gz -C / #解压到/usr/local目录下 sudo mv hadoop-1.1.2 hadoop #重命名为hadoop sudo chown -R python ./hadoop #修改文件权限 //java安装同上给hadoop配置环境变量&#xff0c;将下面代…

从C到C++,C++入门篇(1)

1.什么是C C是一种通用编程语言&#xff0c;由Bjarne Stroustrup在1980年代初开发&#xff0c;作为C语言的扩展。 C支持多种编程范式&#xff0c;包括过程式编程、数据抽象、面向对象编程和泛型编程等。 这种语言在操作系统、游戏开发、图形界面、嵌入式系统、分布式系统、网…

啵啵啵啵啵啵啵啵啵啵啵啵啵啵啵

欢迎关注博主 Mindtechnist 或加入【智能科技社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和技术。关…

“安全生产月”专题报道:AI智能监控技术如何助力安全生产

今年6月是第23个全国“安全生产月”&#xff0c;6月16日为全国“安全宣传咨询日”。今年全国“安全生产月”活动主题为“人人讲安全、个个会应急——畅通生命通道”。近日&#xff0c;国务院安委会办公室、应急管理部对开展好2024年全国“安全生产月”活动作出安排部署。 随着科…

外贸自动化脚本编写会用到的源代码!

随着全球化的加速推进&#xff0c;外贸行业正迎来前所未有的发展机遇&#xff0c;为了提高工作效率、减少人为错误&#xff0c;并更好地把握市场机遇&#xff0c;越来越多的外贸企业开始关注自动化脚本的编写与应用。 自动化脚本不仅可以帮助企业实现业务流程的自动化&#xf…