滑动窗口

博客介绍了滑动窗口(单调队列)的应用,以求窗口里的最小值为例,说明若队列中某个数在i位置前面且比i位置上的数大,无论窗口后移多少位,该数都不可能是最小值,应从队列中移除。

滑动窗口(单调队列)

在这里插入图片描述

拿求窗口里的最小值来说,如果这个数在i位置的前面,还比i位置上的数大,那么无论窗口向后移动多少位,这个数永远不可能是最小值,所以将其从队列中拿出.

#include <bits/stdc++.h>
using namespace std;

#define MAX 1000010

int nArr[MAX];//存储数组的值 
int nQueue[MAX];//队列 里面存储数组的下标

int nSize; 
int nWindow;

int main(int argc, char** argv) 
{
	scanf("%d",&nSize);
	scanf("%d",&nWindow);
	
	//将数组中的元素读取 
	for(int i = 0; i < nSize; i++)
	{
		scanf("%d",&nArr[i]);
	}
	
	int nHead = 0;
	int nTail = -1;
	
	for(int i = 0; i < nSize; i++)
	{
		if(nHead <= nTail && (i - nWindow + 1) > nQueue[nHead])
		{
			//nHead <= nTail保证队列中有元素
			//(i-nWindow+1)与nQueue[nHead]比较 保证当前的下标还在窗口里面 
			nHead++;
		}
		
		while(nHead <= nTail && nArr[nQueue[nTail]] >= nArr[i])
		{
			//在i位置以前的数 还比nArr[i]大的 ,他们的下标都要从里面去除 
			nTail--;
		}
		//当前数组元素入队列
		nQueue[++nTail] = i;
		
		if(i >= nWindow - 1)
		{
			printf("%d ",nArr[nQueue[nHead]]);
		}
	}
	
	printf("\n");
	
	nHead = 0;
	nTail = -1;
	for(int i = 0; i < nSize; i++)
	{
		if(nHead <= nTail && (i - nWindow + 1) > nQueue[nHead])
		{
			//nHead <= nTail保证队列中有元素
			//(i-nWindow+1)与nQueue[nHead]比较 保证当前的下标还在窗口里面 
			nHead++;
		}
		
		while(nHead <= nTail && nArr[nQueue[nTail]] <= nArr[i])
		{
			//在i位置以前的数 还比nArr[i]小的 ,他们的下标都要从里面去除 
			nTail--;
		}
		nQueue[++nTail] = i;
		
		if(i >= nWindow - 1)
		{
			printf("%d ",nArr[nQueue[nHead]]);
		}
	}
	
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值