剑指offer-滑动窗口的最大值
数组长度为N,时间复杂度为O(N)的解法
需要解决的两个问题:
1、如何求当前窗口中的最大值
2、如何判断已经滑离当前窗口,需要弹出操作
主要思路:
利用C++ STL模板库中的 deque(双端队列)去解决
双端队列的操作:
push_back():在队列尾部压入
pop_back() : 从队列尾部弹出
pop_front() :从队列头部弹出
解决问题1:
在双端队列中保存当前最大值的头结点。如果队列为空,直接压入当前节点,例如节点为i。如果不为空,则与队列中尾部的节点(例如节点 j)值比较大小。
如果 a[i]>=a[j], 进行pop_back()操作一直到 当前 j 节点满足a[i]<a[j]。如果a[i]<a[j],压入i。
解决问题2:
当前队列头部<= i-w(节点i,滑动窗口值为w),则说明这个最大值的节点已经不在窗口的范围之内了。
C++代码 vector<int> maxInWindows(const vector<int>& num, unsigned int size)
{
deque<int> windows;
vector<int> result;
if(size<=0 || num.size()<size)//特殊情况
return result;
for(int i = 0;i<size;i++)
{
while(!windows.empty() && num[windows.back()] <=num[i])
{
windows.pop_back();
}
windows.push_back(i);
}
for(int i = size;i<num.size();i++)
{
result.push_back(num[windows.front()]);
while(!windows.empty() && num[windows.back()] <=num[i])
{
windows.pop_back();
}
if(!windows.empty() && windows.front()<=int(i-size))
windows.pop_front();
windows.push_back(i);
}
result.push_back(num[windows.front()]);
return result;
/* 这部分为暴力求解法
vector<int> result;
int max;
if(size==0 || num.size()<size)
return result;
int len = num.size()-size + 1;
for(int i = 0; i < len; i++){
max = 0;
for(int j = i; j < i + size; j++)
{
if(num[j]>max)
max = num[j];
}
result.push_back(max);
}
return result;*/
}
}
};
vector<int> maxInWindows(const vector<int>& num, unsigned int size)
{
deque<int> windows;
vector<int> result;
if(size<=0 || num.size()<size)//特殊情况
return result;
for(int i = 0;i<size;i++)
{
while(!windows.empty() && num[windows.back()] <=num[i])
{
windows.pop_back();
}
windows.push_back(i);
}
for(int i = size;i<num.size();i++)
{
result.push_back(num[windows.front()]);
while(!windows.empty() && num[windows.back()] <=num[i])
{
windows.pop_back();
}
if(!windows.empty() && windows.front()<=int(i-size))
windows.pop_front();
windows.push_back(i);
}
result.push_back(num[windows.front()]);
return result;
/* 这部分为暴力求解法
vector<int> result;
int max;
if(size==0 || num.size()<size)
return result;
int len = num.size()-size + 1;
for(int i = 0; i < len; i++){
max = 0;
for(int j = i; j < i + size; j++)
{
if(num[j]>max)
max = num[j];
}
result.push_back(max);
}
return result;*/
}