have been unable to understand what the monotonous queue is, on the internet can not find an easy-to-understand introduction. Finally combined with other people's blog on the introduction and procedures to understand what is going on.
Let's start with the simplest questions:
Given an integer sequence of length N (i), i=0,1,..., N-1 and window length K.
Requirements:
f (i) = Max{a (i-k+1), A (i-k+2),..., A (i)},i = 0,1,..., N-1
Another description of the problem is that a window with a length of K is moved on an integer sequence to find the maximum value of the number contained within the window.
Solution One:
A very intuitive solution, that is, from the beginning of the sequence, put the window up, and then find the first k number of the maximum value, and then the last window to move a unit, continue to find the maximum number of K.
For each F (i) of this method, the k-1 is compared and the complexity is O (n*k).
So there's no faster algorithm.
Solution Two:
We know that the previous algorithm has a place to repeat the comparison, that is, when looking for the current F (i), I in front of the number of k-1 other in the calculation F (i-1) when we compare. So can we save the last result? Of course, the largest number of the first k-1 in I. The answer is yes, it's going to use a monotonically decreasing queue.
A monotonically descending queue is a queue whose head elements are always the largest in the queue, and the values in the queue are in descending order. We can insert an element from the end of the queue and delete the element from both ends of the queue.
1. First look at the Insert element: In order to guarantee the descending of the queue, when we insert the element V, we want to compare the elements of the tail with V, if the element at the end of the team is not greater than V, delete the element at the end of the tail, and then continue to compare the elements of the new tail with the V, until the end of the element is more than V,
2. The deletion of the end of the team has just been said, then when the first element of the team is deleted. Since we only need to save the maximum value of the first k-1 elements of I, when the index or subscript of the first element of the team is less than i-k+1, it means that the element of the first team is meaningless for f (i) because it is no longer in the window. So when the first element of the index[team]<i-k+1, the first element of the team is deleted.
From the above introduction, we know that the only difference between a monotone queue and a queue is that it not only saves the value of the element, but also saves the index of the element (in practice, of course, we can just save the index and indirectly find the value of the current index through the index).
To make the reader understand a little more, let me give you a simple example.
Suppose the sequence is: 8,7,12,5,16,9,17,2,4,6.n=10,k=3.
Then we construct a monotonically descending queue of length 3:
First, the 8 and its index 0 are put into the queue, and we use (8,0) to indicate that the elements in the queue when each step is inserted are as follows:
0: Insert 8, queue for: (8,0)
1: Insert 7, queue for: (8,0), (7,1)
2: Insert 12, queue for: (12,2)
3: Insert 5, queue for: (12,2), (5,3)
4: Insert 16, queue for: (16,4)
5: Insert 9, queue for: (16,4), (9,5)
。。。。 And so on
Then f (i) is the first element in the queue at step I: 8,8,12,12,16,16, ...
The program code is as follows:
#include <iostream> #include <queue> using namespace std; struct Node {int val; int index;}; void Getmax (int *numsequence,int len, int *result,int k) {Node *que = new Node[len]; int head = 0; int end = 0; for (int i =0;i<len;i++) {Node tmp; tmp.val = numsequence[i]; tmp.index = i; while (end!=0 && que[end].val<=numsequence [i])--end; ++end; Que[end] = tmp; while (end!=0 && que[head].index<i-k+1) ++head; Result[i] = Que[head].val; } Delete []que; } int main () {int len, k; cin>>len>>k; int *numsequence = new Int[len]; int *maxresult = new Int[len]; for (in T i=0;i<len;i++) cin>>numsequence[i]; Getmax (NUMSEQUENCE,LEN,MAXRESULT,K); for (int i=k-1;i<len;i++) cout<<i<< ":" <<maxResult[i]<<endl; Delete[]numsequence; Delete[]maxresult; Numsequence = NULL; Maxresult = NULL; return 0; }