算法训练营第十三天 | LeetCode 239 滑动窗口最大值、LeetCode 347 前K个高频元素

LeetCode 239 滑动窗口最大值

本体初始思路是这样的,首先看下给定数组长度和维持一个滑动窗口所需要花费的时间复杂度之间的关系。初步判断是还行的,当然后面被样例打脸了。需要更新成优先队列的解法。原本的解法能通过37/51和46/51的测试用例。但这还不够,面试时候面试官也不会满意的。

原本代码如下:

class Solution {
private:queue<int> myque;// map<int, int> mymap;int quesize = 0;int maxNum = -10000;void quePushPop(int num) {if (num >= maxNum) {int temp = myque.front();myque.pop();myque.push(num);maxNum = num;// mymap[temp]--;// mymap[num]++;} else {if (myque.front() == maxNum) {int temp  = myque.front();myque.pop();myque.push(num);maxNum = -10000;for (int i = 0; i < quesize; i++) {int temp = myque.front();if (maxNum < temp) maxNum = myque.front();myque.pop();myque.push(temp);}// mymap[num++];// mymap[temp]--;// for (auto it = mymap.rbegin(); it != mymap.rend(); it++) {//     if (it->second > 0) {//         maxNum = it->first;//         break;//     }// }} else {int temp = myque.front();myque.pop();myque.push(num);// mymap[temp]--;// mymap[num]++;}}}
public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {quesize = k;vector<int> res;for (int i = 0; i < k; i++) {if (maxNum < nums[i]) maxNum = nums[i];myque.push(nums[i]);// mymap[nums[i]]++;}res.push_back(maxNum);for (int i = k; i < nums.size(); i++) {quePushPop(nums[i]);res.push_back(maxNum);}return res;}
};

使用优先队列的时候其实也蛮简单。首先定义一个pair<int,int>类型的priority_queue即优先队列,之所以要是一个pair类型是因为需要记录存入数据的下标,pair类型就相当于一个两变量结构体,由于是结构体类型,其变量可以直接用first和second访问,还要注意优先队列进行排序时是依据first值来进行的排序,而且是个最大堆(数组实现的完全二叉树)。首先把前k个元素放入优先队列中,之后先把优先队列最顶端的值放入记录答案的int类型vector中,这里完成了对本题中优先队列的初始化。接着开始下标从k到nums.size() - 1的遍历,这个遍历每次先把nums[i]和i组成pair放入优先队列中,再对堆顶元素的下标值进行判断,如果小于i-k,说明不在窗口中,可以直接pop,一直循环直到该元素在窗口范围内,就可以停止并把该值记录入res并进行下一轮循环了。这样一直到结束,就算是完成了题给需求了,当然此时优先队列中还有很多不在窗口中的值,但他们其实不够大到能够影响结果,所以不用去考虑,这也就是优先队列节省的时间之所在——只考虑最大值。

代码如下:

class Solution {
public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {priority_queue<pair<int, int>> mypri_que;vector<int> res;for (int i = 0; i < k; i++) {mypri_que.push(pair(nums[i],i));}    res.push_back(mypri_que.top().first);for (int i = k; i < nums.size(); i++) {mypri_que.push(pair(nums[i],i));while (mypri_que.top().second <= i - k) mypri_que.pop();res.push_back(mypri_que.top().first);}return res;}
};

附注:虽然这是道困难题,但理解了原理之后也还蛮简单的

LeetCode 347 前K个高频元素

这题要求求出nums数组中出现频率前K高的元素,而且我们可以知道这题要用到优先队列,再加上我之前已经有过的一些思考(想到要用map来记录次数),就很简单了。首先定义一个map,记录数组中每个元素出现的次数,时间复杂度O(n)。再像上一题一样定义一个优先队列,在优先队列中我们将map迭代器it指针的second元素作为优先队列节点的first,将it指针的first元素作为优先队列节点的second,这样维护一个最大堆,之后每次从最大堆中取值,并让其出堆,重复K次,就可以得到我们想要的结果了。在这个过程中,前一过程时间复杂度为O(log(n)*log(n)),后一操作时间复杂度为O(k*log(n)),最大时间复杂度为O(log(n)*log(n)),完美符合条件了。

代码如下:

class Solution {
public:vector<int> topKFrequent(vector<int>& nums, int k) {map<int, int> mymap;priority_queue<pair<int, int>> mypri_que;vector<int> res;for (int i = 0; i < nums.size(); i++) {mymap[nums[i]]++;}for (auto it = mymap.begin(); it != mymap.end(); it++) {mypri_que.push(pair(it->second,it->first));}for (int i = 0; i < k; i++) {res.push_back(mypri_que.top().second);mypri_que.pop();}return res;}
};

之前也说过要补一篇队列的博客,这里就顺便补下吧。首先队列实现起来由于要先入先出,后进的元素又要push到末尾,所以只有一个迭代器来回移动时间复杂度会相当高,所以我们会有两个迭代器,一个是rear作为末尾下标(链式队列中是指针),一个是top作为队首下标(链式队列中是指针)。

顺序数组需要注意的是这是一个从头到尾又到头的数组,即尾下标和头下标分别在入队列和出队列操作时起作用,分别自增,前一个就是正常入队列,在队列尾增加了元素了,后一个就直接将下标后移当成队列中不存在该值,而实际上该内存处如果还没被覆盖,就还是那个值,直到队列再循环一周覆盖它。所以这个队列就完全是一个抽象出来的结构了,实际上它是两个指针构成的一个可以看作窗口的一个结构,不过这个窗口有时候会裂成两半分布在两边。计算大小也是要左右两边分别计算的,rear+1计算0到rear的长度,maxSize(这个是本来就是size + 1了) - front 记录右边的长度。

链式队列感觉就很简单了,就如下图所示

这里front就可以看作平时写题目时的虚拟头节点了。

代码如下:

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Kotlin】Channel简介

1 前言 Channel 是一个并发安全的阻塞队列&#xff0c;可以通过 send 函数往队列中塞入数据&#xff0c;通过 receive 函数从队列中取出数据。 当队列被塞满时&#xff0c;send 函数将被挂起&#xff0c;直到队列有空闲缓存&#xff1b;当队列空闲时&#xff0c;receive 函数将…

python可视化学习笔记折线图问题-起始点问题

问题描述&#xff1a; 起始点的位置不对 from pyecharts.charts import Line import pyecharts.options as opts # 示例数据 x_data [1,2,3,4,5] y_data [1, 2, 3, 4, 5] # 创建 Line 图表 line Line() line.add_xaxis(x_data) line.add_yaxis("test", y_data) li…

基于Hyperf的CMS,企业官网通用php-swoole后台管理系统

2023年9月11日10:47:00 仓库地址&#xff1a; https://gitee.com/open-php/zx-hyperf-cms CMS&#xff0c;企业官网通用PHP后台管理系统 框架介绍 hyperf SCUI 后端开发组件 php 8.1 hyperf 3.1 数据库 sql(使用最新日期文件) hyperf\doc\sql_bak mysql 8. 系统默认账号…

STM32 F103C8T6学习笔记17:类IIC通信—MLX90614红外非接触温度计

今日学习配置MLX90614红外非接触温度计 与 STM32 F103C8T6 单片机的通信 文章提供测试代码讲解、完整工程下载、测试效果图 本文需要用到的大概基础知识&#xff1a;1.3寸OLED配置通信显示、IIC通信、 定时器配置使用 这里就只贴出我的 OLED驱动方面的网址链接了&#xff1a…

ChatGPT4.0知识问答、DALL-E生成AI图片、Code Copilot辅助编程,打开新世界的大门

目录 1、DALL-E 文字转图片 在线AI修改2、Write For Me3、Code Copilot 目前最强的AI编程大模型4、Diagrams: Show Me5、Instant Website [Multipage] 网站合成神器6、AskYourPDF Research Assistant 无限PDF7、Diagrams & Data: Research, Analyze, Visualize 精读Excel …

TCP/IP和HTTP协议

TCP/IP OSI 七层模型在提出时的出发点是基于标准化的考虑&#xff0c;而没有考虑到具体的市场需求&#xff0c;使得该模型结构复杂&#xff0c;部分功能冗余&#xff0c;因而完全实现 OSI 参考模型的系统不多。而 TCP/IP 参考模型直接面向市场需求&#xff0c;实现起来也比较…

LeetCode 543.二叉树的直径

题目描述 给你一棵二叉树的根节点&#xff0c;返回该树的 直径 。 二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。 两节点之间路径的 长度 由它们之间边数表示。 示例 1&#xff1a; 输入&#xff1a;root [1,2,3,4,5]…

报错“Install Js dependencies failed”【鸿蒙开发Bug已解决】

文章目录 项目场景:问题描述原因分析:解决方案:此Bug解决方案总结Bug解决方案寄语项目场景: 最近也是遇到了这个问题,看到网上也有人在询问这个问题,本文总结了自己和其他人的解决经验,解决了【报错“Install Js dependencies failed”】的问题。 报错如下 问题描述 …

【高质量】2024五一数学建模C题保奖思路+代码(后续会更新)

你的点赞收藏是我后续更新的最大动力&#xff01; 一定要点击文末的卡片&#xff0c;那是获取资料的入口&#xff01; 你是否在寻找数学建模比赛的突破点&#xff1f; 作为经验丰富的数学建模团队&#xff0c;我们将为你带来2024 年五一数学建模&#xff08;C题&#xff09;…

复旦微JFM7VX690计算后IO接口模块,用于雷达信号处理、数据处理等需要高速密集计算的应用场景

计算后IO接口模块 1 介绍 1.1 产品概述 计算后IO接口模块主要由复旦微JFM7VX690型FPGA、国产以太网收发器YT8521、国产BMC芯片GD32F450、国产CPLD芯片EF2L45BG256B、国产内存颗粒等主要芯片组成&#xff0c;采用标准6U VPX尺寸设计。 本计算后IO接口模块主要用于雷达信号处…

Nginx负载均衡主备模式

1. 背景 使用Nginx代理后端服务&#xff0c;有时候某些服务是不能使用多台负载均衡&#xff0c;但又想保障高可用&#xff0c;所以采用主备模式&#xff0c;记录如下&#xff1a; 2. 参考 nginx 负载均衡Nginx-负载均衡-后端状态max_conns、down、backup、max_fails、fail_t…

【webrtc】MessageHandler 1: 基于线程的消息处理:以10毫秒处理音频为例

基于m98 G:\CDN\rtcCli\m98\src\audio\null_audio_poller.h分发的消息由MessageHandler 类通过其抽象接口OnMessage 实现处理 NullAudioPoller NullAudioPoller 是一个处理audio的消息的分发器 poll 启动:

2024深圳杯数学建模竞赛A题(东三省数学建模竞赛A题):建立火箭残骸音爆多源定位模型

更新完整代码和成品完整论文 《2024深圳杯&东三省数学建模思路代码成品论文》↓↓↓&#xff08;浏览器打开&#xff09; https://www.yuque.com/u42168770/qv6z0d/zx70edxvbv7rheu7?singleDoc# 2024深圳杯数学建模竞赛A题&#xff08;东三省数学建模竞赛A题&#xff0…

【Go 语言入门专栏】Go 语言的起源与发展

前言 Go 语言是当下最为流行的编程语言之一&#xff0c;大约在 2020、2021 年左右开始于国内盛行&#xff0c;许多大厂很早就将部分 Java 项目迁移到了 Go&#xff0c;足可看出其在性能方面的优越性。 相信各位都知道&#xff0c;在爬虫业务中&#xff0c;并发是一个关键的需…

解决iview(view ui)中tabs组件中使用图片预览组件ImagePreview,图片不显示问题

同学们可以私信我加入学习群&#xff01; 正文开始 前言一、问题描述二、原因分析三、解决方案总结 前言 最近在写个人项目的web端和浏览器插件&#xff0c;其中一个功能是base64和图片的转换。因为分成四个小功能&#xff0c;所以使用的iview的tabs来展示不同功能&#xff0c…

如何解决DA14531编译工程出现大量报错的问题

在编译DA14531某个工程时&#xff0c;在这台电脑可以编译&#xff0c;另外一台电脑就编译不过&#xff0c;出现很多错误问题。那要怎样处理呢&#xff1f; 建议安装新MDK版本 可能是MDK版本问题&#xff0c;在不同的电脑安装不同的MDK版本&#xff0c;用新的版本可以编译通过&…

计算机网络—数据链路层

一、数据链路层的基本概念 结点&#xff1a;主机、路由器 链路&#xff1a;网络中两个结点之间的物理通道&#xff0c;链路的传输介质主要有双绞线、光纤和微波。分为有线链路、无线链路 数据链路&#xff1a;网络中两个结点之间的逻辑通道&#xff0c;把实现控制数据协议的…

java在应用程序里获取不到扬声器设备,如何解决?

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…

MF(推荐系统的矩阵分解技术)论文笔记

论文概述 推荐系统的矩阵分解技术可以为用户提供更为准确的个性化推荐&#xff0c;对比传统的近邻技术&#xff0c;矩阵分解技术可以纳入更多信息&#xff0c;如隐式反馈、时间效应和置信度 近邻技术&#xff1a;基于用户或物品之间的相似性进行推荐&#xff0c;当用户之间已…

针孔相机模型原理坐标系辨析内参标定流程内参变换

针孔相机的内参标定 针孔相机原理真空相机模型图片的伸缩和裁剪变换 内参标定———非线性优化张正定标定详细原理(含公式推导)通过多张棋盘格照片完成相机的内参标定流程(C代码)其他工具箱 相机分为短焦镜头和长焦镜头&#xff0c;短焦镜头看到的视野更广阔&#xff0c;同样距…