一、窗口应用
生成窗口最大值数组
给出一个整形数组,例如arr = {5,4,3,5,6,7,6},窗口大小为w=3,窗口每次向右移动一位,输出每个窗口中最大值组成的数组。
[5,4,3,]5,6,7,6 窗口最大值为5
5,[4,3,5,]6,7,6 窗口最大值为5
5,4,[3,5,6,]7,6 窗口最大值为6
5,4,3,[5,6,7,]6 窗口最大值为7
5,4,3,5,[6,7,6] 窗口最大值为7
则输出的数组为{5,5,6,7,7};
思路:
双端队列,将arr中的元素加入res该队列中,若该队列的队尾元素小于等于要加入的元素,则不断的弹出,直到队尾元素大于该元素或者队列为空。此时将该元素的序号加入队列中。同时当 i-w == 队头的序号,则将队头元素弹出。
代码:
#include<iostream>
#include <deque>
#include <vector>
using namespace std;
vector<int> getMAXWindow(vector<int>vec, int w) {
int len = vec.size();
deque<int> q;
vector<int> res;
if (len <= 0 || w < 1 || len < w) {
return res;
}
for (int i = 0; i < len; i++) {
//往双端队列中加入元素
while (!q.empty() && vec[q.back()] <= vec[i]) {
q.pop_back();
}
q.push_back(i);
//判断当前双端队列的头节点是否过期
if (q.front() == i - w)
q.pop_front();
//当i的值超过w-1后,每次都需要收集当前的最大值
if (i >= w - 1)
res.push_back(vec[q.front()]);
}
return res;
}
int main(void) {
vector<int> vec = { 4,3,5,4,3,3,6,7 };
int w = 3; //窗口大小
vector<int> res = getMAXWindow(vec, w);
for (auto i : res)
cout << i << " ";
system("pause");
return 0;
}
最大值减去最小值小于或等于num的子数组的数量
给定数组 arr 和整数 num,共返回多少个字数组满足如下情况:
max(arr[i...j]) - min(arr[i...j]) <= num
max(arr[i...j]) 表示字数组 arr[i...j] 中的最大值,min(arr[i...j]) 表示子数组 arr[i...j] 中的最小值。
思路:
1.子数组的数量一共为n+(n-1)+...+2+1
2.若 arr[i...j] 满足条件,那么其子数组也会满足条件;
3.若 arr[i...j] 不满组条件,那么包含arr[i...j]的数组都不满足条件;
代码:
#include <iostream>
#include <deque>
using namespace std;
int getNum(int arr[], int len, int num)
{
if (NULL == arr || 0 >= len)
return 0;
deque<int> qmin; //qmLn的第一个数据总是当前数组中最小的数据的位置
deque<int> qmax; //qmax的第一个数据总是当前数组中最大的数据的位置
int L = 0, R = 0, res = 0;
//固定左边,窗口右边一直扩大找符合条件的
while (L < len)
{
while (R < len)
{
while (!qmin.empty() && arr[qmin.front()] >= arr[R])
qmin.pop_back();
qmin.push_back(R);
while (!qmax.empty() && arr[qmax.front() <= arr[R]])
qmax.pop_back();
qmax.push_back(R);
//找到了第一个不符合条件的,后面的R都不符合,
//因为后面的子数组中都包含当前这个不符合的R
if (arr[qmax.front()] - arr[qmin.front()] > num)
break;
R++;
}
res += R - L; //记录当前序列中满足要求的字数组数量
if (qmin.front() == L)
qmin.pop_front();
if (qmax.front() == L)
qmax.pop_front();
L++;//窗口左边界向右移动
}
return res;
}
int main(void)
{
int a[] = { 3