【二叉树】【单调双向队列】LeetCode239:滑动窗口最大值

作者推荐

map|动态规划|单调栈|LeetCode975:奇偶跳

涉及知识点

单调双向队列 二叉树

题目

给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回 滑动窗口中的最大值 。
示例 1:
输入:nums = [1,3,-1,-3,5,3,6,7], k = 3
输出:[3,3,5,5,6,7]
解释:
滑动窗口的位置 最大值


[1 3 -1] -3 5 3 6 7 3
1 [3 -1 -3] 5 3 6 7 3
1 3 [-1 -3 5] 3 6 7 5
1 3 -1 [-3 5 3] 6 7 5
1 3 -1 -3 [5 3 6] 7 6
1 3 -1 -3 5 [3 6 7] 7
示例 2:
输入:nums = [1], k = 1
输出:[1]
参数范围
1 <= nums.length <= 105
-104 <= nums[i] <= 104
1 <= k <= nums.length

单调栈

时间复杂度😮(n)。
queMax中记录(i-k,i],如果i1 < i2,且nums[i1] <=nums[i2],那么i1无论如何都无法成为最大值。故可以淘汰i1,淘汰i1后,成降序排列。队首元素最大。
对queMax有三种操作。

操作一队尾淘汰i1
操作二队尾插入i2
操作三队首删除i-k,由于操作二,queMax不会为空,所以无需判断是否为空。如果i-k已经被操作一淘汰,则不能删除。

代码

核心代码

class Solution {
public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {int i = 0;std::deque<int> queMax;vector<int> vRet;for ( i = 0; i < k; i++){while (queMax.size() && (nums[queMax.back()] <= nums[i])){queMax.pop_back();}queMax.emplace_back(i);			}vRet.emplace_back(nums[queMax.front()]);for (; i < nums.size(); i++){if (i - k == queMax.front()){queMax.pop_front();}while (queMax.size() && (nums[queMax.back()] <= nums[i])){queMax.pop_back();}queMax.emplace_back(i);vRet.emplace_back(nums[queMax.front()]);}return vRet;}
};

测试用例

template<class T>
void Assert(const T& t1, const T& t2)
{assert(t1 == t2);
}template<class T>
void Assert(const vector<T>& v1, const vector<T>& v2)
{if (v1.size() != v2.size()){assert(false);return;}for (int i = 0; i < v1.size(); i++){Assert(v1[i], v2[i]);}
}int main()
{vector<int> nums;int k;{Solution sln;nums = { 1, 3, -1, -3, 5, 3, 6, 7 }, k = 3;auto res = sln.maxSlidingWindow(nums, k);Assert(vector<int>{ 3,3,5,5,6,7 }, res);}{Solution sln;nums = { 1 }, k = 1;auto res = sln.maxSlidingWindow(nums, k);Assert(vector<int>{ 1 }, res);}//CConsole::Out(res);
}

2023年3月二叉树

用多键二叉树(红黑树)mulset记录滑动窗口中的数,由于二叉树默认是升序排列,所以最后一个元素,就是最大值。由于二叉树的插入、删除的时间复杂度是O(logn),故总时间复杂度是O(nlogn)

 class Solution {public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {int i = 0;std::multiset<int> setNums;for (; i + 1 < k; i++){setNums.insert(nums[i]);}vector<int> vRet;for (; i < nums.size(); i++){setNums.insert(nums[i]);vRet.push_back(*setNums.rbegin());auto it = setNums.find(nums[i + 1 - k]);setNums.erase(it);}return vRet;}};

2023年3月第二版

class Solution {
public:
vector maxSlidingWindow(vector& nums, int k) {
vector<pair<int, int>> vValueIndex;
vector vRet;
int iPos = 0;
for (int i = 0; i < nums.size(); i++)
{
while ( ( vValueIndex.size() > iPos ) && (nums[i] >= vValueIndex.back().first))
{
vValueIndex.pop_back();
}
vValueIndex.emplace_back(nums[i], i);
if (i + 1 >= k)
{
vRet.push_back(vValueIndex[iPos].first);
}
if (i + 1 - k == vValueIndex[iPos].second)
{
iPos++;
}
}
return vRet;
}
};

2023年8月版

class Solution{
public:
vector maxSlidingWindow(vector&nums, int k) {
m_c = nums.size();
//每k个元素用一组,vLeft各元素到组首的最大值,vRight各元素到组尾的最大值
vector vLeft(m_c), vRight(m_c);
int iMax = 0;
for (int i = 0; i < m_c; i++)
{
if (0 == i % k)
{
iMax = nums[i];
}
else
{
iMax = max(iMax, nums[i]);
}
vLeft[i] = iMax;
}
iMax = -100 * 1000;
for (int i = m_c-1;i >= 0 ; i-- )
{
if (0 == (i+1) % k)
{
iMax = nums[i];
}
else
{
iMax = max(iMax, nums[i]);
}
vRight[i] = iMax;
}
vector vRet;
for (int i = k-1; i < m_c; i++)
{
vRet.emplace_back( max(vRight[i-k+1], vLeft[i]));
}
return vRet;
}
int m_c;
};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快

速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关

下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法C++ 实现。

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

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

相关文章

如何理解马尔可夫决策过程?

1 引言 马尔可夫性&#xff1a;无后效性&#xff0c;指系统的下个状态只与当前状态信息有关&#xff0c;而与更早之前的状态无关&#xff1b; 马尔可夫链(Markov Chain, MC)&#xff1a;系统的下一个状态只与当前状态相关&#xff1b; 马尔可夫决策过程(Markov Decision Proce…

雷电3接口能干嘛_acasis阿卡西斯推出首款雷电3接口WIFI6网卡:内置Intel AX200

手机、笔记本、平板等智能移动设备已经无声无息成为人们不可或缺的一部分&#xff0c;5G、WiFi是作为信息首发的主要通讯技术。还记得以前连接路由器的人多了就开始卡起来&#xff0c;这是旧式WiFi信道拥堵所造成的&#xff0c;随着技术发展&#xff0c;WiFi从802.11n到802.11a…

萤火虫小程序_9.9元起!萤火虫中秋文化节来了!特价门票限量秒杀,手慢无!...

记忆中关于儿时夏天的美好&#xff1a;睡莲娇绽&#xff0c;绿树成荫&#xff0c;抱着大半个西瓜对着吹风扇&#xff0c;叼着冰棍在院子里玩蛐蛐儿&#xff0c;叫上小伙伴们浅溪里扑棱水&#xff0c;带上手电去树林里寻萤火虫…然而充满浪漫色彩的夏天转瞬即逝&#xff0c;心心…

如何利用录井/测井数据进行学习?

1 数据 数据来源&#xff1a;录井/测井数据。 录井数据的特点&#xff1a; &#xff08;1&#xff09;在钻井过程中采集&#xff1b; &#xff08;2&#xff09;大概1米一个点&#xff1b; &#xff08;3&#xff09;特征包括&#xff1a;钻屑的特征、钻进过程中的油气水的特征…

jmeter 加密解密_犯罪大师入门篇密文答案 谜之解密入门篇密文解题详解_游戏资讯...

第一关犯罪大师入门篇密文答案是什么?犯罪大师谜之解密开启了新的入门篇解密&#xff0c;这次的解密分为四章&#xff0c;每章的内容涉及猪圈密码、埃特巴什密码和元音密码三个内容。因此对玩家来讲难度是很高的&#xff0c;那么具体的答案是什么呢&#xff1f;这里就为大家带…

芯片老化验证流程_一种芯片测试及老化测试装置的制作方法

本实用新型涉及芯片测试技术领域&#xff0c;具体为一种芯片测试及老化测试装置。背景技术&#xff1a;芯片老化测试是一种采用电压和高温来加速器件电学故障的电应力测试方法。老化过程基本上模拟运行了芯片整个寿命&#xff0c;因为老化过程中应用的电激励反映了芯片工作的最…

人工智能+录/测井数据的一些应用举例

1 横波速度的预测&#xff08;油层段&#xff09; https://www.bilibili.com/video/BV1xt4y1B7Mx?spm_id_from333.337.search-card.all.click 2 泥质含量的预测 https://www.bilibili.com/video/BV1tr4y1P7x6?spm_id_from333.337.search-card.all.click 3 甜点和非甜点预…

redmi airdots手动串联_串联谐振试验装置组成图

原标题&#xff1a;串联谐振试验装置组成图湖北中试高测电气控股有限公司技术博士为您解说&#xff1a;串联谐振试验装置组成图中试控股是串联谐振试验装置的生产厂家&#xff0c;串联谐振试验装置主要针对10kV、35kV电缆&#xff0c;35kV主变&#xff0c;交流耐压试验设计制造…

From AlphaGo Zero to 2048论文分享

0 摘要 近年来&#xff0c;游戏 2048 获得了巨大的人气 [6]。游戏允许玩家移动屏幕上的数字&#xff08;2 的幂&#xff0c;例如 2、4、8、16 等&#xff09;&#xff0c;总和至少为 2048。因为它只有 4 个动作&#xff0c;所以很容易上手: 上、下、左、右。但是&#xff0c;很…

云计算的概念_近500亿资金汹涌出逃!云计算概念龙头抛压沉重,科技股资金出逃名单出炉...

数据是个宝数据宝炒股少烦恼两市主力资金全天净流出492.93亿元。科技股今日资金集中流出&#xff0c;云计算概念浪潮信息流出资金超9亿元。受假日外围市场不振影响&#xff0c;A股三大指数低开后弱势震荡&#xff0c;最终集体小幅收跌。截至收盘&#xff0c;沪指下跌0.61%&…

iphone8plus屏幕尺寸_百思买在苹果发布会前列出了一款“iPhone SE Plus”屏幕保护保护膜...

百思买旗下品牌Insignia在苹果“时光飞逝”发布会活动前几个小时&#xff0c;在其网站上开始销售一款名叫“iPhone SE Plus”的屏幕保护贴&#xff0c;尽管预计苹果不会活动上发布任何iPhone。更大的iPhone SE过去一直被各路泄露好手提到&#xff0c;不过普遍认为它会在2021年初…

英文写作句子积累

0 摘要 In this paper, another strategy to learn from multi-label data is studied, where label-specific features are exploited to benefit the discrimination of different class labels. Accordingly, an intuitive yet effective algorithm named LIFT, i.e. multi…

springboot全局常量_Spring-Boot配置属性和环境变量的加载顺序

Spring-Boot使用很方便&#xff0c;创建系统时&#xff0c;您绝对需要将“设置”和“程序”分开&#xff0c;在Java中&#xff0c;有一个名为application.property/yaml的属性文件&#xff0c;但是你想在哪里找到该文件&#xff1f;不&#xff0c;你必须自己创建它。Spring Boo…

手机qq和电脑qq怎么同步消息_手机QQ接入华为HMS!停止运行也能接收消息

腾讯昨日发布了安卓手机QQ 8&#xff0e;4&#xff0e;10正式版&#xff0c;带来了视频包厢、图片提取文字即时翻译、同时扫描多个二维码等新玩法、新功能。据网友&#xff20;皮蛋棒棒糖发现&#xff0c;新版手机QQ已经悄然接入了华为HMS移动服务框架&#xff0c;基于华为提供…

Mathematical Analysis of 2048, The Game论文分享

0 摘要 游戏 2048 席卷了互联网&#xff0c;产生了无数的盗版。 世界各地的人们倾注了数百万小时试图创造 2048 棋子。 除了令人上瘾的游戏外&#xff0c;该游戏还提供了探索数学的有趣机会。 本文试图通过数学归纳法、数论、模糊论和拓扑学对博弈进行数学分析&#xff0c;在此…

maven 公共模块依赖_idea 创建多模块依赖Maven项目

本来网上的教程还算多&#xff0c;但是本着自己有的才是自己的原则&#xff0c;还是自己写一份的好&#xff0c;虽然可能自己也不会真的用得着。1. 创建一个新maven项目2.3. 输入groupid和artifactid&#xff0c;后面步骤直接next&#xff0c;最后finish4.创建好后5. 在主项目名…

安卓手机软件开发_无代码手机app软件开发,让人人都是专业开发工程师

点击上方蓝色字关注我们~近期&#xff0c;谷歌发布了自己的无代码在线app开发平台&#xff0c;这款全新工具旨在让任何一个人都可以轻松进行手机app软件开发。这样的动作无疑指引着安卓软件开发的未来。&#x1f64a;1无代码开发手机app其实由来已久&#xff0c;业内反复讨论了…

Mastering 2048 With Delayed Temporal Coherence Learning, Multistage Weight Promotion论文分享

0 摘要 2048 是一款引人入胜的单人非确定性视频益智游戏&#xff0c;由于简单的规则和难以掌握的游戏玩法&#xff0c;近年来广受欢迎。由于 2048 可以方便地嵌入到离散状态马尔可夫决策过程框架中&#xff0c;我们将其视为评估强化学习中现有和新方法的测试平台。为了开发一个…

python扫描字符串文本时下线_python:SyntaxError:扫描字符串li时的EOL

python&#xff1a;SyntaxError&#xff1a;扫描字符串li时的EOL我在s1"some very long string............"中有上述错误有谁知道我做错了什么&#xff1f;11个解决方案165 votes你没有在行结束前放置"""。如果要执行此操作&#xff0c;请使用"…

AD19 add pins to nets错误_《英雄联盟手游》错误代码问题大全 LOL的错误代码都是什么意思...

英雄联盟手游上线引起广泛的关注&#xff0c;但是有些玩家在进入游戏的时候出现了代码报错的问题&#xff0c;那么针对这些不同的错误代码要如何解决呢?100036 请求超时&#xff0c;网络不好或者加速器速度不够&#xff0c;换个好点的网络或者加速器 10075 100036 账号没有在p…