一个可以找出窗口中最大/小值的数据结构
vector<int> maxval(vector<int> mat,int w)
{
vector<int> res(mat.size()-w+1);
deque<int> q;//用双端队列来表示窗口,队头元素永远是规定窗口中的最大值
for (int i = 0; i < mat.size(); i++)
{
//保证双端队列中的元素从队头到队尾是从大到小排列的
while (!q.empty() && mat[q.back()] <= mat[i])
q.pop_back();
q.push_back(i);
//更新窗口,如果队头元素不在窗口内则弹出队头元素,
if (q.front() <= i - w)
q.pop_front();
if (i - w + 1>=0)
res[i - w + 1] = mat[q.front()]; //获得每个窗口中的最大值
}
return res;
}
//一个数组的子数组的最大值与最小值之差小于num,求得数组中这样的子数组的个数
int numsub(vector<int> vec, int num)
{
deque<int> minq;//利用窗口结构找出子数组中最小值
deque<int> maxq;//利用窗口结构找出子数组中最大值
int res=0,L=0,R=0;
while (L < vec.size())
{
while (R<vec.size())//找出以L为起点的子数组中符合条件的数组
{
while (!minq.empty() && vec[minq.back()]>=vec[R])
minq.pop_back();
minq.push_back(R);
while (!maxq.empty() && vec[maxq.back()]<=vec[R])
maxq.pop_back();
maxq.push_back(R);
if (vec[maxq.front()] - vec[minq.front()]>num)
break;
R++;//保证下一次不需要从头遍历子数组
}
if (minq.front() == L)//更新窗口
minq.pop_front();
if (maxq.front() == L)//更新窗口
maxq.pop_front();
res += (R - L);//加上当前子数组的数量
L++;
}
return res;
}