算法训练营第十三天 | 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就可以看作平时写题目时的虚拟头节点了。

代码如下:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于Spring Boot的校园疫情防控系统设计与实现

基于Spring Boot的校园疫情防控系统设计与实现 开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/idea 系统部分展示 管理员登录首页界面图&#xff0c;管理员进入校园疫…

AI大模型探索之路-训练篇10:大语言模型Transformer库-Tokenizer组件实践

系列篇章&#x1f4a5; AI大模型探索之路-训练篇1&#xff1a;大语言模型微调基础认知 AI大模型探索之路-训练篇2&#xff1a;大语言模型预训练基础认知 AI大模型探索之路-训练篇3&#xff1a;大语言模型全景解读 AI大模型探索之路-训练篇4&#xff1a;大语言模型训练数据集概…

msmpi 高性能并行计算 移植并行细胞自动机报错

报错情况如图 代码来源 元胞自动机生命游戏C语言并行实现 – OmegaXYZ 稍微修改&#xff0c;因为相对路径在 msmpi 10.1.1 中失效 Microsoft Windows [版本 10.0.22000.2538] (c) Microsoft Corporation。保留所有权利。C:\Users\ASUS>mpiexec -n 9 "C:\Users\ASUS\D…

四信数字孪生水库解决方案,加快构建现代化水库运行管理矩阵

近年&#xff0c;水利部先后出台《关于加快构建现代化水库运行管理矩阵的指导意见》与《构建现代化水库运行管理矩阵先行先试工作方案》等文件&#xff0c;明确总体要求及试点水库、先行区域建设技术要求等&#xff0c;为全面推进现代化水库运行管理矩阵建设工作提供依据。 《2…

自定义Maven项目模板Archetype,快速创建模板项目。

自定义Archetype 创建好模板项目&#xff0c;在项目根目录执行命令对模板做出响应调整将模板安装到本地、远程仓库使用自定义模板 创建好模板项目&#xff0c;在项目根目录执行命令 mvn archetype:create-from-project对模板做出响应调整 如果是多模块项目&#xff0c;可能需…

【数据结构】:链表的带环问题

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;数据结构 &#x1f337;追光的人&#xff0c;终会万丈光芒 前言&#xff1a; 链表的带环问题在链表中是一类比较难的问题&#xff0c;它对我们的思维有一个比较高的要求&#xff0c;但是这一类…

【模板】前缀和

原题链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 前缀和模板题。 前缀和中数组下标为1~n。 前缀和&#xff1a;pre[i]pre[i-1]a[i]; 某段区间 [l,r]的和&#xff1a;pre[r]-pre[l-1] 3.…

【C语言】atoi和atof函数的使用

人生应该树立目标&#xff0c;否则你的精力会白白浪费。&#x1f493;&#x1f493;&#x1f493; 目录 •&#x1f319;知识回顾 &#x1f34b;知识点一&#xff1a;atoi函数的使用和实现 • &#x1f330;1.函数介绍 • &#x1f330;2.代码演示 • &#x1f330;3.atoi函数的…

【高校科研前沿】云南大学陈峰研究员联合多家单位在Sci. Bull发文揭示了明末特大干旱背景下北京降水变化及其以太平洋海温变化为主导的驱动新机制

文章简介 论文名称&#xff1a;Coupled Pacific Rim megadroughts contributed to the fall of the Ming Dynasty’s capital in 1644 CE&#xff08;环太平洋地区的特大干旱影响了公元 1644 年明朝的灭亡&#xff09; 第一作者及通讯作者&#xff1a;陈峰研究员&王涛研究…

38-4 Web应用防火墙 - WAF的使用及规则

准备:38-3 Web应用防火墙 - 安装配置WAF-CSDN博客 WAF的使用 启动 Nginx /usr/local/nginx/sbin/nginx 为了测试未启动 ModSecurity 时的访问效果,我们可以模拟攻击。要查看当前虚拟机的 IP 地址,可以使用命令 ifconfig 浏览器中访问ip,如果要在真实机中访问就需要关闭…

Linux 学习 --- 编辑 vi 命令

1、vi 基本概念&#xff08;了解&#xff09; 基本上 vi 可以分为三种状态&#xff0c;分别是命令模式 (command mode)、插入模式 (Insert mode) 和底行模式 (last line mode)&#xff0c;各模式的功能区分如下: 命令行模式 command mode&#xff09;  控制屏幕光标的移动&a…

c3 笔记7 css基本语法

相关内容&#xff1a;字体、段落、词间距、文字效果&#xff08;对齐、上下标、阴影&#xff09;、背景图、背景渐变、…… 单位pt与px的差别pt是印刷使用的字号单位&#xff0c;不管屏幕分辨率是多少&#xff0c;打印到纸上看起来都是相同的&#xff0c;lot的长度是0.01384英寸…

[PS小技能学习]抠图和切图

详情见视频教程&#xff1a;PS小技巧--抠图与切图 今天我们来学习如何使用PS对表情包合辑进行抠图和裁剪保存 1、首先&#xff0c;将图片导入&#xff0c;双击图层新建一个图层 2、然后点击工具栏的魔棒工具&#xff0c;再点击顶部菜单栏的添加到选区 3、点击图片的空白区域即…

《QT实用小工具·五十一》带动画的 CheckBox

1、概述 源码放在文章末尾 该项目实现了带动画效果的多选框&#xff0c;鼠标放在上面或者选中都会呈现炫酷的动画效果&#xff0c;demo演示如下&#xff1a; 项目部分代码如下所示&#xff1a; #ifndef LINEARCHECKBOX_H #define LINEARCHECKBOX_H#include <QCheckBox> …

C/C++不定参函数使用

C语言中不定参函数的使用和访问 例子 例如&#xff0c;这里想写一个打印的函数&#xff0c;但是参数并不确定该怎么办呢&#xff0c;这就要用到不定参函数 #include<stdarg.h> void printNum(int count,...){va_list ap;va_start(ap,count);//获取指定参数的起始地址&…

【CTF Reverse】XCTF GFSJ0492 insanity Writeup(反汇编+字符串搜索)

insanity 菜鸡觉得前面的题目太难了&#xff0c;来个简单的缓一下 解法 拖进 Exeinfo PE 中分析。 -> Compiler : GCC: (Debian 4.4.7-2) 4.4.7用 IDA 打开。 按 shift F12 打开 String 页面。找到 flag。 Flag 9447{This_is_a_flag}声明 本博客上发布的所有关于网络攻…

Java创建并遍历N叉树(前序遍历)

力扣 title589&#xff1a;N叉树的前序遍历 给定一个 n 叉树的根节点 root &#xff0c;返回 其节点值的 前序遍历 。 n 叉树 在输入中按层序遍历进行序列化表示&#xff0c;每组子节点由空值 null 分隔&#xff08;请参见示例&#xff09;。 思路&#xff1a; 1.初始化时…

电脑自带dll修复在哪里,使用dll修复工具解决dll问题

在我们日常与电脑相伴的工作与学习过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中最常见的就是“无法找到.dll”或“找不到.dll文件”。这种情况通常是由于dll文件丢失或损坏导致的。dll文件是动态链接库文件&#xff0c;它包含了许多程序运行所需的函数和资源…

Ant Design助力:实现用户列表的优雅展示与管理

文章目录 概要前端讲解登录组件注册组件用户列表组件 后端讲解连接数据库db.js路由routes.jsexpress应用app.js 启动项目小结 概要 在上一篇博客&#x1f6aa;中&#xff0c;我们已经成功实现了登录注册系统的基本功能。现在&#xff0c;我们将进一步完善系统&#xff0c;实现…

File contains parsing errors: file:///etc/yum.repos.d/nginx.repo报错解决,文件配置出现问题

执行yum指令出现以下错误&#xff1a; 解决方案&#xff1a;yum的配置文件出现问题&#xff0c; 先删除yum.repos.d目录下所有文件 rm -f /etc/yum.repos.d/* 然后重新下载阿里的资源 wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.…