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

news2024/11/16 3:36:12

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.coloradmin.cn/o/1638106.html

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

相关文章

Dynamic-Programming

目录 前言 引入 1) Fibonacci 2) 最短路径 - Bellman-Ford 3) 不同路径-Leetcode 62 4) 0-1 背包问题 降维 5) 完全背包问题 降维 6) 零钱兑换问题-Leetcode322 降维 零钱兑换 II-Leetcode 518 7) 钢条切割问题 降维 类似题目 Leetcode-343 整数拆分 8) 最长…

如何安全的使用密码登录账号(在不知道密码的情况下)

首先&#xff0c;需要用到的这个工具&#xff1a; 度娘网盘 提取码&#xff1a;qwu2 蓝奏云 提取码&#xff1a;2r1z 1、打开工具&#xff0c;进入账号密码模块&#xff0c;如图 2、看到鼠标移动到密码那一栏有提示&#xff0c;按住Ctrl或者Alt点击或者双击就能复制内容&…

Linux(ubuntu)—— 用户管理user 用户组group

一、用户 1.1、查看所有用户 cat /etc/passwd 1.2、新增用户 useradd 命令&#xff0c;我这里用的是2.4的命令。 然后&#xff0c;需要设置密码 passwd student 只有root用户才能用passwd命令设置其他用户的密码&#xff0c;普通用户只能够设置自己的密码 二、组 2.1查看…

人工智能与地理大数据实验--出租车GPS数据—时空大数据Python处理基础(二)

环境&#xff1a;Windows 10 专业版 Python 3.9.1 Anaconda 2020&#xff08; 4.8.2&#xff09; 系列文章&#xff1a; 人工智能与地理大数据实验--出租车GPS数据—时空大数据Python处理基础&#xff08;一&#xff09; 人工智能与地理大数据实验--出租车GPS数据—时空大数据…

接收区块链的CCF会议--APSEC 2024 截止7.13 附录用率

会议名称&#xff1a;APSEC&#xff08;Asia-Pacific Software Engineering Conference&#xff09; CCF等级&#xff1a;CCF C类学术会议 类别&#xff1a;软件工程/系统软件/程序设计语言 录用率&#xff1a;2023年&#xff0c;90 submissions were recommended for accep…

【MATLAB画图】如何绘制图像坐标系

首先我们需要图像坐标轴的原点在左上角&#xff1a; set(gca,ydir,reverse,xaxislocation,top); 然后我们需要坐标轴上加上箭头 quiver(0, 0, 0, 520); % 在(x1, y1)处绘制一个箭头&#xff0c;其方向和长度由(dx, dy)确定 quiver(0, 0, 700, 0); % 在(x1, y1)处绘制一个箭头…

缓存分享(1)——Guava Cache原理及最佳实践

Guava Cache原理及最佳实践 1. Guava Cache是什么1.1 简介1.2 核心功能1.3 适用场景 2. Guava Cache的使用2.1 创建LoadingCache缓存2.2 创建CallableCache缓存 缓存的种类有很多&#xff0c;需要根据不同的应用场景来选择不同的cache&#xff0c;比如分布式缓存如redis、memca…

帕金森患者应该怎么注意生活方式?

在面对帕金森病的挑战时&#xff0c;科学合理地改善日常生活方式&#xff0c;不仅能帮助患者更好地管理病情&#xff0c;还能提升生活质量。今天&#xff0c;让我们一起探索如何通过简单的日常调整&#xff0c;为患有帕金森病的朋友们带来积极的变化。 饮食调整&#xff1a;营养…

MATLAB 函数

MATLAB 函数 函数是一起执行任务的一组语句。在MATLAB中&#xff0c;函数是在单独的文件中定义的。文件名和函数名应该相同。 函数在其自己的工作空间&#xff08;也称为本地工作空间&#xff09;中对变量进行操作&#xff0c;与在MATLAB命令提示符下访问的工作空间&#xff0…

优化|贝叶斯优化系列(一):基础算法原理

贝叶斯优化是一种处理黑盒函数优化问题的重要方法。它通过构建一个目标函数的代理模型&#xff0c;并且利用贝叶斯机器学习方法如高斯过程回归来评估代理模型的不确定性。基于代理模型&#xff0c;通过一个采样函数来决定在哪里进行采样。本推文简单描述了贝叶斯优化方法的框架…

【1小时掌握速通深度学习面试1】卷积神经网络-上

目录 1.简述卷积的基本操作&#xff0c;并分析其与全连接层的区别 2.在卷积神经网络中&#xff0c;如何计算各层的感受野大小?卷积层的输出尺寸、参数量和计算量。 3.简述分组卷积及其应用场景 4.简述空洞卷积的设计思路 5.简述转置卷积的主要思想以及应用场景 1.简述卷积…

8. Django 表单与模型

8. 表单与模型 表单是搜集用户数据信息的各种表单元素的集合, 其作用是实现网页上的数据交互, 比如用户在网站输入数据信息, 然后提交到网站服务器端进行处理(如数据录入和用户登录注册等).网页表单是Web开发的一项基本功能, Django的表单功能由Form类实现, 主要分为两种: dj…

vue3项目引入VueQuill富文本编辑器(成功)及 quill-image-uploader 图像模块(未成功)

tip&#xff1a;重点解释都写在代码注释里了&#xff0c;方便理解&#xff0c;所以看起来比较密集 富文本基本使用 项目文件夹路径安装依赖 npm install vueup/vue-quilllatest --save 全局注册&#xff1a;main.js // main.js// 自己项目的一些配置&#xff08;只放了主要…

IoTDB 入门教程 问题篇①——内存不足导致datanode服务无法启动

文章目录 一、前文二、发现问题三、分析问题四、继续分析五、解决问题 一、前文 IoTDB入门教程——导读 二、发现问题 执行启动命令&#xff0c;但是datanode服务却无法启动&#xff0c;查询不到6667端口 bash sbin/start-standalone.sh 进而导致数据库连接也同样失败 [rooti…

开箱子咸鱼之王H5游戏源码_内购修复优化_附带APK完美运营无bug最终版__GM总运营后台_附带安卓版本

内容目录 一、详细介绍二、效果展示2.效果图展示 三、学习资料下载 一、详细介绍 1.包括原生打包APK&#xff0c;资源全部APK本地化&#xff0c;基本上不跑服务器宽带 2.优化后端&#xff0c;基本上不再一直跑内存&#xff0c;不炸服响应快&#xff01; 3.优化前端&#xff0c…

Linux开发板 FTP 服务器移植与搭建

VSFTPD&#xff08;Very Secure FTP Daemon&#xff09;是一个安全、稳定且快速的FTP服务器软件&#xff0c;广泛用于Unix和Linux操作系统。它以其轻量级、高效和易于配置而受到赞誉。VSFTPD不仅支持标准的FTP命令和操作&#xff0c;还提供了额外的安全特性&#xff0c;如匿名F…

会声会影2024中文旗舰版最新网盘安装包下载

会声会影2024是一款功能强大的视频编辑软件&#xff0c;它凭借直观易用的界面、全面的编辑工具以及丰富的特效库&#xff0c;吸引了广泛的用户群体。无论是视频编辑初学者还是专业人士&#xff0c;都能在这款软件中找到满足自己创作需求的功能。 一、软件概述 会声会影2024继承…

【c++】模板编程解密:C++中的特化、实例化和分离编译

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;c笔记仓 朋友们大家好&#xff0c;本篇文章我们来学习模版的进阶部分 目录 1.非类型模版参数按需实例化 2.模版的特化函数模版特化函数模版的特化类模版全特化偏特化 3.分离编译模版分离编译 1.非类…

Android(Java)项目支持Kotlin语言开发

Android&#xff08;Java&#xff09;项目通过相关Kotlin设置后&#xff0c;允许同时使用Java语言和Kotlin语言进行开发代码的。 示例环境&#xff1a; Android Studio Giraffe | 2022.3.1 Patch 3 Java 8 Kotlin 1.9.20 设置Kotlin选项&#xff1a; 第一步&#xff1a;在项…

ASP.NET淘宝店主交易管理系统的设计与实现

摘 要 淘宝店主交易管理系统主要采用了ASPACCESS的B/S设计模式&#xff0c;通过网络之间的数据交换来实现客户、商品、交易的管理和对客户、商品、交易统计工作&#xff0c;从而提高淘宝店主在管理网店过程中的工作效率和质量。 系统分为基本资料模块&#xff0c;统计资料模…