65、滑动窗口的最大值
解决思路:利用双端队列维护m(m <=k)个窗口,使得每次滑动保证队列头部是k个窗口的最大值。
1)先维护的m个窗口使得队列头部的值最大。如果当前值大于等于队尾的值,弹出队尾的值, 当前值放入队尾。把头部放入vector。
2)依次滑动,如果当前值大于等于队尾的值,弹出队尾的值, 当前值放入队尾。每次滑动后判断队头和队尾下标的差值是否大于等于k, 如果大于等于k,则弹出队头的值。最后把新的头部的值放入vector
#include <iostream>
#include <vector>
#include <algorithm>
#include <deque>
using namespace std;
void maxInMoveWindows(const vector<int> &A, int k){
//queue 和 pair 集合使用
pair<int, int> p;
deque<pair<int, int> > dq;
vector<int> aMax;
int len = A.size();
int cnt = 0;
int Max = -1;
//先维护的m个窗口使得队列头部的值最大
while (cnt < k){
//如果当前值大于等于队尾的值,弹出队尾的值
while(dq.size() > 0 && A[cnt] >= dq.back().second)
dq.pop_back();
//当前值放入队尾
p.first = cnt; p.second = A[cnt]; dq.push_back(p);
cnt ++;
}
aMax.push_back(dq.front().second);
//依次滑动
for (int i = k; i < len;i ++){
//如果当前值大于等于队尾的值,弹出队尾的值
while(dq.size() > 0 && A[i] >= dq.back().second)
dq.pop_back();
//当前值放入队尾
p.first = i; p.second = A[i]; dq.push_back(p);
//每次滑动后判断队头和队尾下标的差值是否大于等于k,
//如果大于等于k,则弹出队头的值。
if (dq.back().first - dq.front().first >= k)
dq.pop_front();
//最后把新的头部的值放入vector
aMax.push_back(dq.front().second);
}
for (int i = 0;i < aMax.size(); i ++)
cout << aMax[i] << endl;
}
int main(){
vector<int> A = {2,3,4,2,6,2,5,1};
maxInMoveWindows(A, 3);
}