2022-11-23 11:57阅读: 27评论: 0推荐: 0

力扣-239-滑动窗口的最大值

居然是道困难题,与之相比,子序列只是道简单题

拆分成两个步骤:

  1. 维持滑动窗口
  2. 找出窗口中的最大值

那么能不能将这两个步骤统一呢?

考虑每次都是取走滑动窗口的第一个元素,新插入最后一个元素

  • 如果取走元素不是最大元素,这个好说,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 中国大陆许可协议进行许可。

posted @   YaosGHC  阅读(27)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起