算法训练营第十三天 | 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.mzph.cn/diannao/5886.shtml

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

相关文章

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-6.5--I.MX6U启动方式

前言&#xff1a; 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM&#xff08;MX6U&#xff09;裸机篇”视频的学习笔记&#xff0c;在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…

导航系统架构及业务模块组合策略导读

系列文章目录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 TODO:写完再整理 文章目录 系列文章目录前言一、嵌入式硬件系统架构【开发系统平台架构】通讯方式及组件选型方向导航机器人硬件配置及其常用功能 二、嵌入式软件系统组件…

VS Code工具将json数据格式化

诉求&#xff1a;json数据格式化应该在工作中用到的地方特别多&#xff0c;为了更方便、更仔细的对json数据查看&#xff0c;将json数据格式化是非常有必要的。 VS Code中如何将json数据快速格式化 1、在VS Code中安装Beautify JSON插件 2、安装完后在需要格式化的文件中按住…

Web APIs 学习归纳6--- BOM浏览器对象

前面几节主要针对DOM进行了学习&#xff0c;现在开始新的内容的学习---DOM浏览器对象。 DOM是更注重页面&#xff08;document&#xff09;内容的设计&#xff0c;但是BOM不仅限于页面&#xff08;document&#xff09;的设计&#xff0c;而是更加全面包括页面的刷新&#xff0…

【linux学习指南】linux指令与实践文件编写

文章目录 &#x1f4dd;前言&#x1f320; linux目录结构&#x1f309;linux命令介绍 &#x1f320;pwd命令&#x1f309;mkdir指令&#xff08;重要&#xff09; &#x1f320;cd 指令&#x1f309;touch指令 &#x1f320;rmdir指令 && rm 指令&#xff08;重要&…

抖音评论区精准获客自动化获客释放双手

挺好用的&#xff0c;评论区自动化快速获客&#xff0c;如果手动点引流涨&#xff0c;那就很耗费时间了&#xff0c;不是吗&#xff1f; 网盘自动获取 链接&#xff1a;https://pan.baidu.com/s/1lpzKPim76qettahxvxtjaQ?pwd0b8x 提取码&#xff1a;0b8x

Dashboard 安装部署

Dashboard 安装部署 Dashboard 安装部署 一&#xff1a;下载 二&#xff1a;部署步骤 1.镜像下载及导入 国内直接拉外网镜像会失败&#xff0c;可在境外下载镜像 查看 deployment 里的镜像版本 Dashboard Deploymentcontainers:- name: kubernetes-dashboardimage: k8s.g…

C++中的指针详解

C中的指针详解 在C编程中&#xff0c;指针是一个非常重要且基础的概念。它允许程序员直接访问和操作内存地址&#xff0c;为高级数据结构和算法的实现提供了基础。本文将详细讲解C中指针的概念、用法和注意事项&#xff0c;帮助读者深入理解并掌握指针的相关知识。 一、指针的…

C++ 多线程中捕捉异常

有一个主线程&#xff0c;有一个子线程。主线程中调用子线程&#xff0c;并检查是否抛出异常&#xff0c;如果异常就处理异常信息。 主要思路&#xff1a;定义一个全局的std::exception_ptr对象&#xff0c;子线程抛异常时赋给该指针&#xff0c;主线程中检查该对象&#xff0…

四. Django项目之电商购物商城 -- 图片验证码生成

Django项目之电商购物商城 – 图片验证码生成 需要开发文档和前端资料的可私聊 一. 图片验证码的生成 1. 创建应用用于生成图片验证码 , 以及短信验证码 python manage.py startapp verfications2.配置radis数据库 "var_code":{# 配置数据库指定引擎"BACKE…

访问网站提示502 Bad Gateway的原因和解决方法

"502 Bad Gateway"错误通常表示服务器作为网关或代理服务器尝试访问上游服务器(如应用服务器或其他代理服务器)&#xff0c;但未能从上游服务器接收到有效的响应。以下是可能导致此错误的一些常见原因以及相应的解决方法&#xff1a; 1. 服务器端问题&#xff1a; 服…

Unity Audio Filter 入门

概述&#xff1a; 如果你在你项目中需要一些特殊的声音效果&#xff0c;那这部分声音过滤器的部分一定不要错过喔&#xff0c;让我们来学习这部分的内容吧&#xff01; 这部分理论性比较强&#xff0c;认真看我的注解哈&#xff0c;我尽量解释的易懂一点。 Audio Chorus Filter…

Intelij Idea Push失败,出现git Authentication failed(验证失败)

目录 1、出现问题的原因 2、解决之法 1、出现问题的原因 能出现这种问题&#xff0c;最主要的原因是链接对上了&#xff0c;但用户验证失败了&#xff0c;即登录失败。 因为服务器转移或者换了git项目链接&#xff0c;导致你忘记了用户名密码&#xff0c;随意输入之后&…

持续更新|UNIAPP适配APP遇到的问题以及解决方案

在使用UNIAPP开发APP的时候遇到的一些奇奇怪怪问题记录 组件样式丢失 问题&#xff1a;组件引入界面中&#xff0c;在小程序和H5环境下样式正常&#xff0c;而在APP中却出现高度异常问题 解决&#xff1a;增加view标签将组件包裹起来即可正常显示 解决前&#xff1a; 解决后…

数据结构:实验七:数据查找

一、 实验目的 &#xff08;1&#xff09;领会各种查找算法的过程和算法设计。 &#xff08;2&#xff09;掌握查找算法解决实际问题。 二、 实验要求 &#xff08;1&#xff09;编写一个程序exp8-1.cpp, 按提示输入10个任意的整形数据&#xff08;无序&#xff09;&…

socat移植到arm+linux

socat是一个用于建立双向数据流传输的工具&#xff0c;它可以在不同的网络层上创建连接&#xff0c;并支持多种协议&#xff0c;如TCP、UDP、SSL等。它非常强大且易于使用&#xff0c;因此广泛用于网络开发和系统管理中&#xff0c;这里记录一下移植到嵌入式系统的过程。 下载s…

每天学习一个Linux命令之sed

每天学习一个Linux命令之sed 欢迎来到我的博客系列&#xff0c;今天我们将学习一个非常强大的Linux命令——sed&#xff0c;它可以在文本处理中实现各种强大的操作。sed&#xff08;Stream Editor&#xff09;是Linux环境下的一种流编辑器&#xff0c;可以对文件内容进行替换、…

Mysql_数据库事务

文章目录 &#x1f60a; 作者&#xff1a;Lion J &#x1f496; 主页&#xff1a; https://blog.csdn.net/weixin_69252724 &#x1f389; 主题&#xff1a; MySQL__事务&#xff09; ⏱️ 创作时间&#xff1a;2024年04月26日 ———————————————— 这里写目…

服务端不 listen 可以创建 tcp 连接吗

这个问题有三类答案。 上来就撸 linux kernel 源码&#xff0c;折腾半天&#xff0c;哦&#xff0c;终于在 tcp_rcv_state_process 里找到了 tcp_rcv_synsent_state_process 调用&#xff0c;后者包含&#xff1a; if (th->syn) {/* We see SYN without ACK. It is attemp…

【golang-ent】go-zero框架 整合 ent orm框架实现一对一 一对多 多种姿势查询方式

一、ent的 O2O 问题 官方文档如下: https://entgo.io/zh/docs/schema-edges#o2o-same-type 1、ent O2O问题 官方提供了三种 one2one的方式,可以看到他全部使用了 mysql的 foregionKey 的方式进行关联,虽然举例了单表和双表的不同使用方式,但是我们实际使用mysql中是不创建…