家谱网站源码下载,企业网站排版规则,怎么创建一个公司网站,制作app费用题目描述
给定一个数组和滑动窗口的大小#xff0c;找出所有滑动窗口里数值的最大值。例如#xff0c;如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3#xff0c;那么一共存在6个滑动窗口#xff0c;他们的最大值分别为{4,4,6,6,6,5}#xff1b; 针对数组{2,3,4,2,6,2,…题目描述
给定一个数组和滑动窗口的大小找出所有滑动窗口里数值的最大值。例如如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3那么一共存在6个滑动窗口他们的最大值分别为{4,4,6,6,6,5} 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个 {[2,3,4],2,6,2,5,1} {2,[3,4,2],6,2,5,1} {2,3,[4,2,6],2,5,1} {2,3,4,[2,6,2],5,1} {2,3,4,2,[6,2,5],1} {2,3,4,2,6,[2,5,1]}。
解题思路
方案一蛮力法顺序分块扫描。例如在上例中我们进行不断的分组和查找3个一组这样最终会找出其最大值。但是其时间复杂度为O(NK)。N为滑动窗口的数量K为滑动窗口的大小。方案二双端队列实现。由于方案二中实现的步骤比较复杂所以我们换了一种思路在取得最大值的过程中我们并不把每个数值都存入队列而只是把有可能成为最大值的数据存入到两端开口的队列(deque)中上面的输入为例其求解过程如下 代码实现
class Solution {vectorint res;dequeint q;
public:vectorint maxInWindows(const vectorint num, unsigned int size){if(num.size()size size 1) //保证参数合理性{//取一个窗口中的最大值的下标for(int i0;isize;i){if(!q.empty() num[q.back()]num[i])q.pop_back();q.push_back(i);}//处理后面for(int i size;inum.size();i){//每回将一个窗口中的最大值压入结果集合//最大值永远是以队列头元素为下标的值res.push_back(num[q.front()]);//如果后面元素大小有比以队列中任何一个元素为下标的元素大的话//把队列清空while(!q.empty() num[q.back()] num[i])q.pop_back();//如果后面的元素没有比当前最大元素大但是窗口已经满了滑过了最大元素的下标if(!q.empty() q.front() i-size)q.pop_front();q.push_back(i);}//最后一次循环结束i到头最后一个窗口中的最大值就是//以队列中头元素为下标的值res.push_back(num[q.front()]);}return res;}
};