用一个双端队列,队列第一个位置保存当前窗口的最大值,当窗口滑动一次
1.判断当前最大值是否过期
2.新增加的值从队尾开始比较,把所有比他小的值丢掉
单调队列,O(n)
链接:http://www.nowcoder.com/practice/1624bc35a45c42c0bc17d17fa0cba788?rp=4&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
/** 题目描述 给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。 例如,如果输入数组{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]}。 用一个双端队列,队列第一个位置保存当前窗口的最大值,当窗口滑动一次 1.判断当前最大值是否过期 2.新增加的值从队尾开始比较,把所有比他小的值丢掉 单调队列,O(n) */ #include<cstdio> #include<vector> #include<deque> #include<iostream> #include<algorithm> using namespace std; class Solution { public: vector<int> maxInWindows(const vector<int>& num, unsigned int size) { vector<int> ans; if(num.size()<size || num.size()==0 || size<=0) return ans; deque<int> tmp; //双端队列 int len=size,mmax=-1,mj=-1; for(int i=0;i<len;i++) { if(num[i]>mmax) { mmax=num[i]; mj=i; } } for(int i=mj;i<len;i++) tmp.push_back(i); //应该把len里最大值之后的所有下标放入容器。而不是单单的 // tmp.push_back(mj);//前len里最大值的下标放入 ans.push_back(mmax);//将前len里最大值放入 for(int i=len;i<num.size();i++) { // deque<int>::iterator iter=tmp.begin(); // while(iter!=tmp.end()) // { // cout<<*iter++<<" "; // }cout<<endl; int t=num[i]; int k=tmp.front(); //最大值的下标 if(i-k >= len) //去掉已经过时的最大值!!! { while(i-k >= len) { tmp.pop_front(); if(!tmp.empty()) k=tmp.front(); else {tmp.push_back(i);break;} } } int j=tmp.back(); //最后一个值的下标 //加入新的数,并覆盖前面能覆盖的比自己小的值 if(i!=j && num[i]>=num[j]) { while(num[i]>=num[j]) { tmp.pop_back(); if(!tmp.empty()) j=tmp.back(); else break; } tmp.push_back(i); } else tmp.push_back(i); k=tmp.front(); ans.push_back(num[k]); } return ans; } }; int main() { vector<int> arr; unsigned int len=3; /* arr.push_back(2); arr.push_back(3); arr.push_back(4); arr.push_back(4); arr.push_back(6); arr.push_back(2); arr.push_back(3); arr.push_back(2); arr.push_back(5); arr.push_back(1); */ arr.push_back(16); arr.push_back(14); arr.push_back(12); arr.push_back(10); arr.push_back(8); arr.push_back(6); arr.push_back(4); arr.push_back(2); /* arr.push_back(2); arr.push_back(3); arr.push_back(4); arr.push_back(2); arr.push_back(6); arr.push_back(2); arr.push_back(5); arr.push_back(1); */ Solution so; arr=so.maxInWindows(arr,len); vector<int>::iterator iter=arr.begin(); while(iter!=arr.end()) { cout<<*iter++<<" "; }cout<<endl; return 0; }
这些天的在学车,,,题目什么的,很久没做了,,,马上就要考科二了,只求飘过。