239.滑动窗口最大值

一个和 滑动窗口有关的题目 官方给出了三种解法  很值得借鉴

方法一: priority_queue O(nlogn)

        使用模板库的优先队列保存pair(i, nums[i])  

        在取最大值 .top()  的时候   注意 看一看它的下标在不在范围内(<=i-k), 不在的时候需要把它(队首元素)pop出去   每次push或者pop的时间复杂度都是log n 

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

方法二: 性质破局

        注意到窗口是向右移动的  所以对于下标i,j (i<j)  当 i 和 j 都在窗口中时,如果nums[i] <= nums[j] ,那么显然这个时候就 nums[i]就不会是窗口的最大值(之后也不会)

        所以我们可以把nums[i] 删除 ,针对此题   我们可以维护一个单调队列

        显然从队头到队尾(从左到右) 数值应该是严格单调递减的 不然不满足上面的性质

        每次加入新元素的时候,如果比当前的队尾要小就直接加入 ,否则就把排在它前面但是数值比它还要小或者和它相等的元素一一删除,以此保证单调性 

        在每次取元素的时候, 取队头 同时保证这个元素的下标可以在当前的范围内也就是(<=n-k)

class Solution {
public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {deque<int> dq;//单调队列   左边下标小的是头   右边下标大的是尾部//如果i<j  而且 nums[i] <= nums[j] 那么 i不会是最大值//所以可以把nums[i]去掉//所以随着下标从小到大  数值应该是从大到小//所以每次新来一个nums[k]都应该拿它和 队尾(最小的元素) 比较//如果新来的更小  ->  加入//如果新来的大    ->  把小于等于它的都删除   再加入for(int i=0;i<k;i++){while(!dq.empty() && nums[dq.back()] <= nums[i] ){dq.pop_back();}dq.push_back(i);}vector<int> ans={ nums[dq.front()] };for(int i=k;i<nums.size();i++){while(!dq.empty() && nums[dq.back()] <= nums[i] ){dq.pop_back();}dq.push_back(i);while(dq.front() <= i-k ){dq.pop_front();}ans.push_back( nums[dq.front()] );}return ans;}
};

方法三: 分组 + 前后缀

        还有一个有意思的做法就是分组   把元素k个一组分开 ,最后一组可能不足k个

        然后计算nums[i]这个元素在它所在的分组里面的最大前后缀,记为prefix[i] 和 suffix[i]

窗口和组的关系只用两种:

        1. 当前窗口刚好是一个分组 比较第一个元素的最大后缀 or 最后一个元素的最大前缀

        2.当前窗口跨越前后两个分组 计算前一个组最大后缀 和 后一个组最大前缀 进行比较        

归结起来都是 ans[i] = max(suffix[i] , prefix[i+k-1])

前后缀的计算如图:  这个如果对前后缀 有一点了解可以自己简单递推

class Solution {
public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {vector<int> prefix(nums.size()); //分组前缀中的maxvector<int> suffix(nums.size()); //分组后缀中的maxfor(int i=0;i<nums.size();i++){if(i%k==0){prefix[i] = nums[i];}else{prefix[i] = max(prefix[i-1] , nums[i]);}}for(int i=nums.size()-1;i>=0;i--){if(i==nums.size()-1 || (i+1)%k == 0){suffix[i] = nums[i];}else{suffix[i] = max(nums[i] , suffix[i+1]);}}vector<int> ans(nums.size()+1-k);for(int i=0;i+k-1<nums.size();i++){ans[i] = max(suffix[i] , prefix[i+k-1]);}return ans;}
};

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

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

相关文章

Meta正打造一个巨型AI模型,旨在为其“整个视频生态系统”提供动力,一位高管透露

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

【Linux】gcc与make、makefile

文章目录 1 gcc/g1.1 预处理1.2 编译1.3 汇编1.4 链接1.4.1 静态链接1.4.2 动态链接 2 make和makefile2.1 依赖关系2.2 依赖方法2.3 伪目标 3 总结 1 gcc/g 当我们创建一个文件&#xff0c;并向里面写入代码&#xff0c;此时&#xff0c;我们该如何使我们的代码能够运行起来呢&…

java中使用rabbitmq

文章目录 前言一、引入和配置1.引入2.配置 二、使用1.队列2.发布/订阅2.1 fanout(广播)2.2 direct(Routing/路由)2.3 Topics(主题)2.4 Headers 总结 前言 mq常用于业务解耦、流量削峰和异步通信,rabbitmq是使用范围较广,比较稳定的一款开源产品,接下来我们使用springboot的sta…

保姆级认识AVL树【C++】(三种insert情况 || 四种旋转方法)

目录 前言 一&#xff0c;AVL概念 二&#xff0c;基础框架 三&#xff0c;insert 1. 插入三种情况 2. 四种旋转方法 法一&#xff1a;左单旋法 法二&#xff1a;右单旋法 法三&#xff1a;先左后右双旋法 法四&#xff1a;先右后左双旋法 测试&#xff08;判断一棵树…

修改简化docker命令

修改|简化docker命令 使用命令打开 .bashrc 文件&#xff1a; vim ~/.bashrc在文件中添加类似以下行来创建别名&#xff1a; # 查看所有容器 alias disdocker images # 查看运行容器 alias dpsdocker ps # 查看所有容器 alias dpsadocker ps -a # 停止容器 alias dsdocker s…

基于智慧灯杆的智慧城市解决方案(2)

功能规划 智慧照明功能 智慧路灯的基本功能仍然是道路照明, 因此对照明功能的智慧化提升是最基本的一项要求。 对道路照明管理进行智慧化提升, 实施智慧照明, 必然将成为智慧城市中道路照明发展的主要方向之一。 智慧照明是集计算机网络技术、 通信技术、 控制技术、 数据…

Data Concerns Modeling Concerns

How was the data you are using collected? What assumptions is your model making by learning from this dataset? Is this dataset representative enough to produce a useful model? How could the results of your work be misused? What is the intended use and …

第15章——西瓜书规则学习

1.序贯覆盖 序贯覆盖是一种在规则学习中常用的策略&#xff0c;它通过逐步构建规则集来覆盖训练数据中的样本。该策略采用迭代的方式&#xff0c;每次从训练数据中选择一部分未被覆盖的样本&#xff0c;学习一条能够覆盖这些样本的规则&#xff0c;然后将这条规则加入到规则集中…

【Python】成功解决ModuleNotFoundError: No module named ‘matplotlib‘

【Python】成功解决ModuleNotFoundError: No module named ‘matplotlib’ &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1f448…

Linux系统安装及简单操作

目录 一、Linux系统安装 二、Linux系统启动 三、Linux系统本地登录 四、Linux系统操作方式 五、Linux的七种运行级别&#xff08;runlevel&#xff09; 六、shell 七、命令 一、Linux系统安装 场景1&#xff1a;直接通过光盘安装到硬件上&#xff08;方法和Windows安装…

基于springboot实现摄影网站系统项目【项目源码】

基于springboot实现摄影网站系统演示 摘要 随着时代的进步&#xff0c;社会生产力高速发展&#xff0c;新技术层出不穷信息量急剧膨胀&#xff0c;整个社会已成为信息化的社会人们对信息和数据的利用和处理已经进入自动化、网络化和社会化的阶段。如在查找情报资料、处理银行账…

虚拟化

什么是虚拟化 虚拟化&#xff08;Virtualization&#xff09;是一种资源分配和管理技术&#xff0c;是将计算机的各种实体资源,比如CPU、内存、磁盘空间、网络适配器等&#xff0c;进行抽象转换后虚拟的设备,可以实现灵活地分割、组合为一个或多个计算机配置环境&#xff0c;并…