力扣-239-滑动窗口的最大值
居然是道困难题,与之相比,子序列只是道简单题
拆分成两个步骤:
- 维持滑动窗口
- 找出窗口中的最大值
那么能不能将这两个步骤统一呢?
考虑每次都是取走滑动窗口的第一个元素,新插入最后一个元素
- 如果取走元素不是最大元素,这个好说,
maxNum = max(maxNum,newNum)
- 如果取走的就是maxNum,如果没有相同的数字还好说,但是如果窗口中有不止一个maxNum呢?也就是最大值重复的情况
// 不得已扫描一遍整个序列,找出最大值 int findMax(vector<int>& nums, int left, int right) { int maxNum=nums[left]; for (int i = left+1; i <= right; i++) maxNum = max(maxNum, nums[i]); return maxNum; } vector<int> maxSlidingWindow(vector<int>& nums, int k) { vector<int> res(1); for (int i = 0; i < nums.size(); i++) { // 初始化滑动窗口 if (i < k) res[0] = max(res[0], nums[i]); else { if (nums[i] >= res[i-k]) res.push_back(nums[i]); else { // 如果被丢出去的是最大值,但是没法保证剩下的里面没有重复的最大值,所以只能扫描一遍 if (nums[i-k] = res[i - k]) res.push_back(findMax(nums, i-k+1, i)); // 被丢出去的不是最大值,新加入的又没有最大值大,那最大值仍旧是最大值 else res.push_back(res[i - k]); } } } return res; }
这是我的第一版代码,很直接的思路,我也知道那个全序列扫描绝对是瓶颈,测试用例也不负所望,给了k=5000的不当人用例,果然难和40几的通过率不是白来的
可能得换个思路才行了
我想到了二维动态规划
// 定义dp[i][j]表示从第i个元素开始,到第j个元素为止的最大值 // 状态转移方程为:横向:dp[i][j] = max(dp[i][j-1],nums[j]) // 纵向为:dp[i][j]=
好像也不对,这么定义的话这是一个上三角,而且也多了很多冗余
官解
优先队列…和单调队列
都听过见过,但也仅限于此
优先队列就是堆,那么它和普通队列有什么区别?
单调队列以前遇到过一次,具体哪个题忘记了
优先队列解法
vector<int> maxSlidingWindow(vector<int>& nums, int k) { vector<int> res; priority_queue<pair<int,int>> window; // 好,既然会用优先队列了,就用优先队列解决这个问题 // 但问题是,它改变了队列的原始顺序,我怎么pop第一个元素呢?并不能pop指定元素 // 什么意思?其实并不需要每一个都pop,如果本应pop的元素不是最大值,因为我们只关心最大值,所以pop与否没有影响 // 但是如果待pop元素就是最大值,那么直接pop堆顶就可以了 // 这也是题目提示中的意思,这个队列的大小并不需要是固定的 for (int i = 0; i < nums.size(); i++) { window.emplace(nums[i],i); if (i >= k-1) { while (window.top().second < i - k + 1) window.pop(); res.push_back(window.top().first); } } // 不行,这里不pop其实是对后面有影响的,必须有个机制在某个时间将左边界左侧的元素排除 // 实现这一点是通过保存一个额外的索引来实现的 // 这个时机是在res取之前,保证这个max确实是在窗口中的 return res; }
空间效率很不理想,时间效率也不算好
根本上是来自于堆的空间占用和堆的调整用时上面,虽然不用自己实现,但是过程消耗是真实存在的
堆排序时间复杂度O(n logn),空间复杂度O(1)
单调队列解法
我去看了单调队列,说实话没看明白,等二刷吧
本文作者:YaosGHC
本文链接:https://www.cnblogs.com/yaocy/p/16917838.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步