基础数据结构第五期 滑动窗口


前言

滑动窗口其实跟双指针算法差不多,该部分好理解,但是代码确实是不好写,不过没关系,多练几次就熟练了!!!

一、滑动窗口是什么?

滑动窗口究其本质就是一种基于双指针的思想,两个指针指向的元素之间形成一个窗口。

常见的滑动窗口有两类:

  • 固定大小类的窗口
  • 大小动态变化的窗口

二、典型例题

1.例题

基础数据结构第五期 滑动窗口_第1张图片

2.AC代码(数组模拟+STL)

数组模拟:

#include

using namespace std;

typedef long long ll;
const int N = 1000010;

int n,a[N],q[N],k;
int main()
{
	scanf("%d%d",&n,&k);
	for(int i = 0; i< n;i++)scanf("%d",&a[i]);
	int hh=0,tt = -1;
	//求窗口内的最小值
	for(int i=0;iq[hh]) hh++;
		while( hh <= tt && a[q[tt]] >= a[i]) tt--;//头部到尾部由大到小排列
		q[++tt] = i;//尾部入队
		if(i>=k-1) printf("%d ",a[q[hh]]);
	}
	puts("");
	hh=0,tt=-1;//清空队列
	for(int i=0;iq[hh]) hh++;
		while(hh <= tt && a[q[tt]] <= a[i]) tt--;//头部到尾部由小到大排列
		q[++tt] = i;//尾部入队
		if(i>=k-1) printf("%d ",a[q[hh]]);
	}//用数组模拟队列、栈更快
	puts("");
	return 0;
}

STL:

#include
#include
using namespace std;
const int N=1e6+10;
int a[N],minn[N],maxn[N],n,k;//minn  maxn记录不同的滑动窗口中的不同的最值
deque maxi,mini;//单调队列
int main()
{
    cin>>n>>k;
    for(int i=1;i<=n;i++)
    cin>>a[i];
    maxi.push_front(1);//现将第一个值输入进去
    mini.push_front(1);
    maxn[1]=1;//同样也是将第一个值输入进去
    minn[1]=1;
 k--;
    for(int i=2;i<=n;i++)
    {
        while(mini.size()&&mini.front()+k=a[i])//实现队列单调,在队列中一直是从小到大
        mini.pop_back();
        while(maxi.size()&&a[maxi.back()]<=a[i])//实现队列单调,在队列中一直是从大到小
      
        maxi.pop_back();
        mini.push_back(i);
        maxi.push_back(i);
        minn[i]=mini.front();//对头就是最大值和最小值
        maxn[i]=maxi.front();
    }
    for(int i=k+1;i<=n;i++)
    cout<

总结

观察上列代码不难发现,数组模拟更简单应该熟练掌握,STL相对较为复杂,但是只要明白其原理然后多加练习就可以熟能生巧的,感谢大家的观看!!!

你可能感兴趣的:(#数据结构与算法,数据结构)