D- sliding window

ZJM 有一个长度为 n 的数列和一个大小为 k 的窗口, 窗口可以在数列上来回移动. 现在 ZJM想知道在窗口从左往右滑的时候,每次窗口内数的最大值和最小值分别是多少. 例如: 
数列是 [1 3 -1 -3 5 3 6 7], 其中 k 等于 3. 
Window position                   Minimum value                Maximum value
[1  3  -1] -3  5  3  6  7                -1                           3
 1 [3  -1  -3] 5  3  6  7                -3                           3
 1  3 [-1  -3  5] 3  6  7                -3                           5
1  3  -1 [-3  5  3] 6  7                 -3                           5
1  3  -1  -3 [5  3  6] 7                  3                           6
 1  3  -1  -3  5 [3  6  7]                3                           7

Input:

Enter two lines. The first line of two integers n and k are the size and length of the sliding window series, 1 <= k <= n <= 1000000. The second row has n represents an integer number of columns of ZJM.

Output:

There are two lines of output. The first output line of each sliding window position from left to right, the minimum value in the sliding window. The second line is the maximum.

Sample Input:

8 3
1 3 -1 -3 5 3 6 7

Sample Output:

1 -3 -3 -3 3 3
3 3 5 5 6 7

Topic analysis:

  • To find this topic in the sliding window of the local minimum and maximum values ​​can be used to find the most monotonous stack, stack monotonous but more important it is to emphasize the monotony of global, so here uses monotone monotony of maintenance of local queue.

    • having a first team monotone queue and dequeue certain elements than the foregoing elements back into the first team's properties, when the head of the queue element is not in the interval can be dequeued.
    • Time complexity is consistent with the monotony of the stack.

  • Double ended queue in the deque call STL, each queue maintains a monotonically increasing, and a monotonic decreasing queue obtains the minimum and maximum current window, when the element does not belong to the current window, the pop-up head of the queue element; when the element is not monotone, when the team last element pops up, otherwise join the queue from the tail. Finally, minimum and maximum values ​​are sequentially output to each window.

Code:

#include<iostream>
#include<stdio.h>
#include<deque>
using namespace std;
const int maxn=1e6+10;
int n,k;
int amin[maxn],amax[maxn];
void solve(int *a)//单调增队列 
{
	deque<int> q;
	for(int i=0;i<n;i++)
	{
		while(q.size()>0 &&( i-q.front() )>=k)//不在窗口内弹出 
		{
			q.pop_front();
		}
		while(q.size()>0 && a[i]<a[q.back()])//不满足单调性弹出
		{
			q.pop_back();
		}
		q.push_back(i);
		amin[i]=a[q.front()];
	} 
	for(int i=k-1;i<n;i++)
	{
		printf("%d ",amin[i]);
	}
}
void solve1(int *a)//单调减队列 
{
	deque<int> q;
	for(int i=0;i<n;i++)
	{
		while(q.size()>0 &&( i-q.front() )>=k)//不在窗口内弹出 
		{
			q.pop_front();
		}
		while(q.size()>0 && a[i]>a[q.back()])//不满足单调性弹出
		{
			q.pop_back();
		}
		q.push_back(i);
		amax[i]=a[q.front()];
	}
	for(int i=k-1;i<n;i++)
	{
		printf("%d ",amax[i]);
	} 
}
int main()
{
	
	scanf("%d%d",&n,&k);//数列长度和窗口大小
	int *a=new int[n]; 
	for(int i=0;i<n;i++)
	{
		scanf("%d",&a[i]);
	}
	solve(a);
	printf("\n");
	solve1(a); 
	return 0;
} 
Published 21 original articles · won praise 0 · Views 1094

Guess you like

Origin blog.csdn.net/qq_43746837/article/details/105013983