Improve language
This commit is contained in:
parent
8de82088dc
commit
20eff084ec
592
chapter08.tex
592
chapter08.tex
|
@ -11,10 +11,10 @@ and how many times the loops are performed.
|
||||||
However, sometimes a straightforward analysis
|
However, sometimes a straightforward analysis
|
||||||
does not give a true picture of the efficiency of the algorithm.
|
does not give a true picture of the efficiency of the algorithm.
|
||||||
|
|
||||||
\key{Amortized analysis} can be used for analyzing
|
\key{Amortized analysis} can be used to analyze
|
||||||
algorithms that contain operations whose
|
algorithms that contain operations whose
|
||||||
time complexity varies.
|
time complexity varies.
|
||||||
The idea is to estimate the total time used for
|
The idea is to estimate the total time used to
|
||||||
all such operations during the
|
all such operations during the
|
||||||
execution of the algorithm, instead of focusing
|
execution of the algorithm, instead of focusing
|
||||||
on individual operations.
|
on individual operations.
|
||||||
|
@ -24,23 +24,22 @@ on individual operations.
|
||||||
\index{two pointers method}
|
\index{two pointers method}
|
||||||
|
|
||||||
In the \key{two pointers method},
|
In the \key{two pointers method},
|
||||||
two pointers are used for
|
two pointers are used to
|
||||||
iterating through the elements in an array.
|
iterate through the array values.
|
||||||
Both pointers can move during the algorithm,
|
Both pointers can move to one direction only,
|
||||||
but each pointer can move to one direction only.
|
which ensures that the algorithm works efficiently.
|
||||||
This restriction ensures that the algorithm works efficiently.
|
Next we discuss two problems that can be solved
|
||||||
|
|
||||||
We will next discuss two problems that can be solved
|
|
||||||
using the two pointers method.
|
using the two pointers method.
|
||||||
|
|
||||||
\subsubsection{Subarray sum}
|
\subsubsection{Subarray sum}
|
||||||
|
|
||||||
As the first example,
|
As the first example,
|
||||||
we consider a problem where we are
|
consider a problem where we are
|
||||||
given an array of $n$ positive numbers
|
given an array of $n$ positive integers
|
||||||
and a target sum $x$,
|
and a target sum $x$,
|
||||||
and we should find a subarray whose sum is $x$
|
and we want to find a subarray whose sum is $x$
|
||||||
or report that there is no such subarray.
|
or report that there is no such subarray.
|
||||||
|
|
||||||
For example, the array
|
For example, the array
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tikzpicture}[scale=0.7]
|
\begin{tikzpicture}[scale=0.7]
|
||||||
|
@ -54,16 +53,6 @@ For example, the array
|
||||||
\node at (5.5,0.5) {$1$};
|
\node at (5.5,0.5) {$1$};
|
||||||
\node at (6.5,0.5) {$2$};
|
\node at (6.5,0.5) {$2$};
|
||||||
\node at (7.5,0.5) {$3$};
|
\node at (7.5,0.5) {$3$};
|
||||||
%
|
|
||||||
% \footnotesize
|
|
||||||
% \node at (0.5,1.4) {$1$};
|
|
||||||
% \node at (1.5,1.4) {$2$};
|
|
||||||
% \node at (2.5,1.4) {$3$};
|
|
||||||
% \node at (3.5,1.4) {$4$};
|
|
||||||
% \node at (4.5,1.4) {$5$};
|
|
||||||
% \node at (5.5,1.4) {$6$};
|
|
||||||
% \node at (6.5,1.4) {$7$};
|
|
||||||
% \node at (7.5,1.4) {$8$};
|
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
contains a subarray whose sum is 8:
|
contains a subarray whose sum is 8:
|
||||||
|
@ -80,32 +69,21 @@ contains a subarray whose sum is 8:
|
||||||
\node at (5.5,0.5) {$1$};
|
\node at (5.5,0.5) {$1$};
|
||||||
\node at (6.5,0.5) {$2$};
|
\node at (6.5,0.5) {$2$};
|
||||||
\node at (7.5,0.5) {$3$};
|
\node at (7.5,0.5) {$3$};
|
||||||
%
|
|
||||||
% \footnotesize
|
|
||||||
% \node at (0.5,1.4) {$1$};
|
|
||||||
% \node at (1.5,1.4) {$2$};
|
|
||||||
% \node at (2.5,1.4) {$3$};
|
|
||||||
% \node at (3.5,1.4) {$4$};
|
|
||||||
% \node at (4.5,1.4) {$5$};
|
|
||||||
% \node at (5.5,1.4) {$6$};
|
|
||||||
% \node at (6.5,1.4) {$7$};
|
|
||||||
% \node at (7.5,1.4) {$8$};
|
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
It turns out that the problem can be solved in
|
This problem can be solved in
|
||||||
$O(n)$ time by using the two pointers method.
|
$O(n)$ time by using the two pointers method.
|
||||||
The idea is to use
|
The idea is maintain pointers that point to the
|
||||||
left and right pointers that indicate the
|
first and last value of a subarray.
|
||||||
first and last element of an subarray.
|
|
||||||
On each turn, the left pointer moves one step
|
On each turn, the left pointer moves one step
|
||||||
forward, and the right pointer moves forward
|
to the right, and the right pointer moves to the right
|
||||||
as long as the subarray sum is at most $x$.
|
as long as the resulting subarray sum is at most $x$.
|
||||||
If the sum becomes exactly $x$,
|
If the sum becomes exactly $x$,
|
||||||
a solution has been found.
|
a solution has been found.
|
||||||
|
|
||||||
As an example, consider the following array
|
As an example, consider the following array
|
||||||
with target sum $x=8$:
|
and a target sum $x=8$:
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tikzpicture}[scale=0.7]
|
\begin{tikzpicture}[scale=0.7]
|
||||||
\draw (0,0) grid (8,1);
|
\draw (0,0) grid (8,1);
|
||||||
|
@ -118,23 +96,11 @@ with target sum $x=8$:
|
||||||
\node at (5.5,0.5) {$1$};
|
\node at (5.5,0.5) {$1$};
|
||||||
\node at (6.5,0.5) {$2$};
|
\node at (6.5,0.5) {$2$};
|
||||||
\node at (7.5,0.5) {$3$};
|
\node at (7.5,0.5) {$3$};
|
||||||
%
|
|
||||||
% \footnotesize
|
|
||||||
% \node at (0.5,1.4) {$1$};
|
|
||||||
% \node at (1.5,1.4) {$2$};
|
|
||||||
% \node at (2.5,1.4) {$3$};
|
|
||||||
% \node at (3.5,1.4) {$4$};
|
|
||||||
% \node at (4.5,1.4) {$5$};
|
|
||||||
% \node at (5.5,1.4) {$6$};
|
|
||||||
% \node at (6.5,1.4) {$7$};
|
|
||||||
% \node at (7.5,1.4) {$8$};
|
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
Initially, the subarray contains the elements
|
The initial subarray contains the values
|
||||||
1, 3 and 2, and the sum of the subarray is 6.
|
1, 3 and 2 whose sum is 6:
|
||||||
The subarray cannot be larger, because
|
|
||||||
the next element 5 would make the sum larger than $x$.
|
|
||||||
|
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tikzpicture}[scale=0.7]
|
\begin{tikzpicture}[scale=0.7]
|
||||||
|
@ -152,22 +118,12 @@ the next element 5 would make the sum larger than $x$.
|
||||||
|
|
||||||
\draw[thick,->] (0.5,-0.7) -- (0.5,-0.1);
|
\draw[thick,->] (0.5,-0.7) -- (0.5,-0.1);
|
||||||
\draw[thick,->] (2.5,-0.7) -- (2.5,-0.1);
|
\draw[thick,->] (2.5,-0.7) -- (2.5,-0.1);
|
||||||
%
|
|
||||||
% \footnotesize
|
|
||||||
% \node at (0.5,1.4) {$1$};
|
|
||||||
% \node at (1.5,1.4) {$2$};
|
|
||||||
% \node at (2.5,1.4) {$3$};
|
|
||||||
% \node at (3.5,1.4) {$4$};
|
|
||||||
% \node at (4.5,1.4) {$5$};
|
|
||||||
% \node at (5.5,1.4) {$6$};
|
|
||||||
% \node at (6.5,1.4) {$7$};
|
|
||||||
% \node at (7.5,1.4) {$8$};
|
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
Then, the left pointer moves one step forward.
|
Then, the left pointer moves one step to the right.
|
||||||
The right pointer does not move, because otherwise
|
The right pointer does not move, because otherwise
|
||||||
the sum would become too large.
|
the subarray sum would exceed $x$.
|
||||||
|
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tikzpicture}[scale=0.7]
|
\begin{tikzpicture}[scale=0.7]
|
||||||
|
@ -185,24 +141,14 @@ the sum would become too large.
|
||||||
|
|
||||||
\draw[thick,->] (1.5,-0.7) -- (1.5,-0.1);
|
\draw[thick,->] (1.5,-0.7) -- (1.5,-0.1);
|
||||||
\draw[thick,->] (2.5,-0.7) -- (2.5,-0.1);
|
\draw[thick,->] (2.5,-0.7) -- (2.5,-0.1);
|
||||||
%
|
|
||||||
% \footnotesize
|
|
||||||
% \node at (0.5,1.4) {$1$};
|
|
||||||
% \node at (1.5,1.4) {$2$};
|
|
||||||
% \node at (2.5,1.4) {$3$};
|
|
||||||
% \node at (3.5,1.4) {$4$};
|
|
||||||
% \node at (4.5,1.4) {$5$};
|
|
||||||
% \node at (5.5,1.4) {$6$};
|
|
||||||
% \node at (6.5,1.4) {$7$};
|
|
||||||
% \node at (7.5,1.4) {$8$};
|
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
Again, the left pointer moves one step forward,
|
Again, the left pointer moves one step to the right,
|
||||||
and this time the right pointer moves three
|
and this time the right pointer moves three
|
||||||
steps forward.
|
steps to the right.
|
||||||
The sum is $2+5+1=8$, so we have found a subarray
|
The subarray sum is $2+5+1=8$, so a subarray
|
||||||
where the sum of the elements is $x$.
|
whose sum is $x$ has been found.
|
||||||
|
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tikzpicture}[scale=0.7]
|
\begin{tikzpicture}[scale=0.7]
|
||||||
|
@ -220,30 +166,20 @@ where the sum of the elements is $x$.
|
||||||
|
|
||||||
\draw[thick,->] (2.5,-0.7) -- (2.5,-0.1);
|
\draw[thick,->] (2.5,-0.7) -- (2.5,-0.1);
|
||||||
\draw[thick,->] (4.5,-0.7) -- (4.5,-0.1);
|
\draw[thick,->] (4.5,-0.7) -- (4.5,-0.1);
|
||||||
%
|
|
||||||
% \footnotesize
|
|
||||||
% \node at (0.5,1.4) {$1$};
|
|
||||||
% \node at (1.5,1.4) {$2$};
|
|
||||||
% \node at (2.5,1.4) {$3$};
|
|
||||||
% \node at (3.5,1.4) {$4$};
|
|
||||||
% \node at (4.5,1.4) {$5$};
|
|
||||||
% \node at (5.5,1.4) {$6$};
|
|
||||||
% \node at (6.5,1.4) {$7$};
|
|
||||||
% \node at (7.5,1.4) {$8$};
|
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
The time complexity of the algorithm depends on
|
The running time of the algorithm depends on
|
||||||
the number of steps the right pointer moves.
|
the number of steps the right pointer moves.
|
||||||
There is no useful upper bound how many steps the
|
There is no useful upper bound how many steps the
|
||||||
pointer can move on a single turn.
|
pointer can move on a single turn.
|
||||||
However, the pointer moves \emph{a total of}
|
However, the pointer moves \emph{a total of}
|
||||||
$O(n)$ steps during the algorithm,
|
$O(n)$ steps during the algorithm,
|
||||||
because it only moves forward.
|
because it only moves to the right.
|
||||||
|
|
||||||
Since both the left and right pointer
|
Since both the left and right pointer
|
||||||
move $O(n)$ steps during the algorithm,
|
move $O(n)$ steps during the algorithm,
|
||||||
the time complexity is $O(n)$.
|
the algorithm works in $O(n)$ time.
|
||||||
|
|
||||||
\subsubsection{2SUM problem}
|
\subsubsection{2SUM problem}
|
||||||
|
|
||||||
|
@ -253,24 +189,24 @@ Another problem that can be solved using
|
||||||
the two pointers method is the following problem,
|
the two pointers method is the following problem,
|
||||||
also known as the \key{2SUM problem}:
|
also known as the \key{2SUM problem}:
|
||||||
we are given an array of $n$ numbers and
|
we are given an array of $n$ numbers and
|
||||||
a target sum $x$, and our task is to find two numbers
|
a target sum $x$, and our task is to find
|
||||||
in the array such that their sum is $x$,
|
two array values such that their sum is $x$,
|
||||||
or report that no such numbers exist.
|
or report that no such values exist.
|
||||||
|
|
||||||
To solve the problem, we first
|
To solve the problem, we first
|
||||||
sort the numbers in the array in increasing order.
|
sort the array values in increasing order.
|
||||||
After that, we iterate through the array using
|
After that, we iterate through the array using
|
||||||
two pointers.
|
two pointers.
|
||||||
The left pointer starts at the first element
|
The left pointer starts at the first value
|
||||||
and moves one step forward on each turn.
|
and moves one step to the right on each turn.
|
||||||
The right pointer begins at the last element
|
The right pointer begins at the last value
|
||||||
and always moves backward until the sum of the
|
and always moves to the left until the sum of the
|
||||||
elements is at most $x$.
|
left and right value is at most $x$.
|
||||||
If the sum of the elements is exactly $x$,
|
If the sum is exactly $x$,
|
||||||
a solution has been found.
|
a solution has been found.
|
||||||
|
|
||||||
For example, consider the following array
|
For example, consider the following array
|
||||||
with target sum $x=12$:
|
and a target sum $x=12$:
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tikzpicture}[scale=0.7]
|
\begin{tikzpicture}[scale=0.7]
|
||||||
\draw (0,0) grid (8,1);
|
\draw (0,0) grid (8,1);
|
||||||
|
@ -283,22 +219,12 @@ with target sum $x=12$:
|
||||||
\node at (5.5,0.5) {$9$};
|
\node at (5.5,0.5) {$9$};
|
||||||
\node at (6.5,0.5) {$9$};
|
\node at (6.5,0.5) {$9$};
|
||||||
\node at (7.5,0.5) {$10$};
|
\node at (7.5,0.5) {$10$};
|
||||||
%
|
|
||||||
% \footnotesize
|
|
||||||
% \node at (0.5,1.4) {$1$};
|
|
||||||
% \node at (1.5,1.4) {$2$};
|
|
||||||
% \node at (2.5,1.4) {$3$};
|
|
||||||
% \node at (3.5,1.4) {$4$};
|
|
||||||
% \node at (4.5,1.4) {$5$};
|
|
||||||
% \node at (5.5,1.4) {$6$};
|
|
||||||
% \node at (6.5,1.4) {$7$};
|
|
||||||
% \node at (7.5,1.4) {$8$};
|
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
The initial positions of the pointers
|
The initial positions of the pointers
|
||||||
are as follows.
|
are as follows.
|
||||||
The sum of the numbers is $1+10=11$
|
The sum of the values is $1+10=11$
|
||||||
that is smaller than $x$.
|
that is smaller than $x$.
|
||||||
|
|
||||||
\begin{center}
|
\begin{center}
|
||||||
|
@ -318,21 +244,11 @@ that is smaller than $x$.
|
||||||
|
|
||||||
\draw[thick,->] (0.5,-0.7) -- (0.5,-0.1);
|
\draw[thick,->] (0.5,-0.7) -- (0.5,-0.1);
|
||||||
\draw[thick,->] (7.5,-0.7) -- (7.5,-0.1);
|
\draw[thick,->] (7.5,-0.7) -- (7.5,-0.1);
|
||||||
%
|
|
||||||
% \footnotesize
|
|
||||||
% \node at (0.5,1.4) {$1$};
|
|
||||||
% \node at (1.5,1.4) {$2$};
|
|
||||||
% \node at (2.5,1.4) {$3$};
|
|
||||||
% \node at (3.5,1.4) {$4$};
|
|
||||||
% \node at (4.5,1.4) {$5$};
|
|
||||||
% \node at (5.5,1.4) {$6$};
|
|
||||||
% \node at (6.5,1.4) {$7$};
|
|
||||||
% \node at (7.5,1.4) {$8$};
|
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
Then the left pointer moves one step forward.
|
Then the left pointer moves one step to the right.
|
||||||
The right pointer moves three steps backward,
|
The right pointer moves three steps to the left,
|
||||||
and the sum becomes $4+7=11$.
|
and the sum becomes $4+7=11$.
|
||||||
|
|
||||||
\begin{center}
|
\begin{center}
|
||||||
|
@ -352,20 +268,10 @@ and the sum becomes $4+7=11$.
|
||||||
|
|
||||||
\draw[thick,->] (1.5,-0.7) -- (1.5,-0.1);
|
\draw[thick,->] (1.5,-0.7) -- (1.5,-0.1);
|
||||||
\draw[thick,->] (4.5,-0.7) -- (4.5,-0.1);
|
\draw[thick,->] (4.5,-0.7) -- (4.5,-0.1);
|
||||||
%
|
|
||||||
% \footnotesize
|
|
||||||
% \node at (0.5,1.4) {$1$};
|
|
||||||
% \node at (1.5,1.4) {$2$};
|
|
||||||
% \node at (2.5,1.4) {$3$};
|
|
||||||
% \node at (3.5,1.4) {$4$};
|
|
||||||
% \node at (4.5,1.4) {$5$};
|
|
||||||
% \node at (5.5,1.4) {$6$};
|
|
||||||
% \node at (6.5,1.4) {$7$};
|
|
||||||
% \node at (7.5,1.4) {$8$};
|
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
After this, the left pointer moves one step forward again.
|
After this, the left pointer moves one step to the right again.
|
||||||
The right pointer does not move, and a solution
|
The right pointer does not move, and a solution
|
||||||
$5+7=12$ has been found.
|
$5+7=12$ has been found.
|
||||||
|
|
||||||
|
@ -386,39 +292,27 @@ $5+7=12$ has been found.
|
||||||
|
|
||||||
\draw[thick,->] (2.5,-0.7) -- (2.5,-0.1);
|
\draw[thick,->] (2.5,-0.7) -- (2.5,-0.1);
|
||||||
\draw[thick,->] (4.5,-0.7) -- (4.5,-0.1);
|
\draw[thick,->] (4.5,-0.7) -- (4.5,-0.1);
|
||||||
%
|
|
||||||
% \footnotesize
|
|
||||||
% \node at (0.5,1.4) {$1$};
|
|
||||||
% \node at (1.5,1.4) {$2$};
|
|
||||||
% \node at (2.5,1.4) {$3$};
|
|
||||||
% \node at (3.5,1.4) {$4$};
|
|
||||||
% \node at (4.5,1.4) {$5$};
|
|
||||||
% \node at (5.5,1.4) {$6$};
|
|
||||||
% \node at (6.5,1.4) {$7$};
|
|
||||||
% \node at (7.5,1.4) {$8$};
|
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
The algorithm consists of two phases:
|
The running time of the algorithm is
|
||||||
First, sorting the array takes $O(n \log n)$ time.
|
$O(n \log n)$, because it first sorts
|
||||||
After this, the left pointer moves $O(n)$ steps
|
the array in $O(n \log n)$ time,
|
||||||
forward, and the right pointer moves $O(n)$ steps
|
and then both pointers move $O(n)$ steps.
|
||||||
backward. Thus, the total time complexity
|
|
||||||
of the algorithm is $O(n \log n)$.
|
|
||||||
|
|
||||||
Note that it is possible to solve the problem
|
Note that it is possible to solve the problem
|
||||||
in another way in $O(n \log n)$ time using binary search.
|
in another way in $O(n \log n)$ time using binary search.
|
||||||
In such a solution, we iterate through the array
|
In such a solution, we iterate through the array
|
||||||
and for each number, we try to find another
|
and for each array value, we try to find another
|
||||||
number such that the sum is $x$.
|
value that yields the sum $x$.
|
||||||
This can be done by performing $n$ binary searches,
|
This can be done by performing $n$ binary searches,
|
||||||
and each search takes $O(\log n)$ time.
|
each of which takes $O(\log n)$ time.
|
||||||
|
|
||||||
\index{3SUM problem}
|
\index{3SUM problem}
|
||||||
A more difficult problem is
|
A more difficult problem is
|
||||||
the \key{3SUM problem} that asks to
|
the \key{3SUM problem} that asks to
|
||||||
find \emph{three} numbers in the array
|
find \emph{three} array values
|
||||||
such that their sum is $x$.
|
whose sum is $x$.
|
||||||
Using the idea of the above algorithm,
|
Using the idea of the above algorithm,
|
||||||
this problem can be solved in $O(n^2)$ time\footnote{For a long time,
|
this problem can be solved in $O(n^2)$ time\footnote{For a long time,
|
||||||
it was thought that solving
|
it was thought that solving
|
||||||
|
@ -432,8 +326,8 @@ Can you see how?
|
||||||
|
|
||||||
\index{nearest smaller elements}
|
\index{nearest smaller elements}
|
||||||
|
|
||||||
Amortized analysis is often used for
|
Amortized analysis is often used to
|
||||||
estimating the number of operations
|
estimate the number of operations
|
||||||
performed on a data structure.
|
performed on a data structure.
|
||||||
The operations may be distributed unevenly so
|
The operations may be distributed unevenly so
|
||||||
that most operations occur during a
|
that most operations occur during a
|
||||||
|
@ -441,28 +335,24 @@ certain phase of the algorithm, but the total
|
||||||
number of the operations is limited.
|
number of the operations is limited.
|
||||||
|
|
||||||
As an example, consider the problem
|
As an example, consider the problem
|
||||||
of finding for each element
|
of finding the \key{nearest smaller element}
|
||||||
of an array the
|
of each array element, i.e.,
|
||||||
\key{nearest smaller element}, i.e.,
|
the first smaller element that precedes the element
|
||||||
the first smaller element that precedes
|
in the array.
|
||||||
the element in the array.
|
|
||||||
It is possible that no such element exists,
|
It is possible that no such element exists,
|
||||||
in which case the algorithm should report this.
|
in which case the algorithm should report this.
|
||||||
It turns out that the problem can be solved
|
Next we will see how the problem can be
|
||||||
in $O(n)$ time using an appropriate data structure.
|
efficiently solved using a stack structure.
|
||||||
|
|
||||||
An efficient solution to the problem is to
|
We go through the array from left to right
|
||||||
iterate through the array from left to right
|
and maintain a stack of array elements.
|
||||||
and maintain a chain of elements where the
|
At each array position, we remove elements from the stack
|
||||||
first element is the current element
|
until the top element is smaller than the
|
||||||
and each following element is the nearest smaller
|
current element, or the stack is empty.
|
||||||
element of the previous element.
|
Then, we report that the top element is
|
||||||
If the chain only contains one element,
|
the nearest smaller element of the current element,
|
||||||
the current element does not have a nearest smaller element.
|
or if the stack is empty, there is no such element.
|
||||||
At each step, elements are removed from the chain
|
Finally, we add the current element to the stack.
|
||||||
until the first element is smaller
|
|
||||||
than the current element, or the chain is empty.
|
|
||||||
After this, the current element is added to the chain.
|
|
||||||
|
|
||||||
As an example, consider the following array:
|
As an example, consider the following array:
|
||||||
\begin{center}
|
\begin{center}
|
||||||
|
@ -477,21 +367,11 @@ As an example, consider the following array:
|
||||||
\node at (5.5,0.5) {$3$};
|
\node at (5.5,0.5) {$3$};
|
||||||
\node at (6.5,0.5) {$4$};
|
\node at (6.5,0.5) {$4$};
|
||||||
\node at (7.5,0.5) {$2$};
|
\node at (7.5,0.5) {$2$};
|
||||||
%
|
|
||||||
% \footnotesize
|
|
||||||
% \node at (0.5,1.4) {$1$};
|
|
||||||
% \node at (1.5,1.4) {$2$};
|
|
||||||
% \node at (2.5,1.4) {$3$};
|
|
||||||
% \node at (3.5,1.4) {$4$};
|
|
||||||
% \node at (4.5,1.4) {$5$};
|
|
||||||
% \node at (5.5,1.4) {$6$};
|
|
||||||
% \node at (6.5,1.4) {$7$};
|
|
||||||
% \node at (7.5,1.4) {$8$};
|
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
First, the numbers 1, 3 and 4 are added to the chain,
|
First, the elements 1, 3 and 4 are added to the stack,
|
||||||
because each number is larger than the previous number.
|
because each element is larger than the previous element.
|
||||||
Thus, the nearest smaller element of 4 is 3,
|
Thus, the nearest smaller element of 4 is 3,
|
||||||
and the nearest smaller element of 3 is 1.
|
and the nearest smaller element of 3 is 1.
|
||||||
\begin{center}
|
\begin{center}
|
||||||
|
@ -508,25 +388,23 @@ and the nearest smaller element of 3 is 1.
|
||||||
\node at (6.5,0.5) {$4$};
|
\node at (6.5,0.5) {$4$};
|
||||||
\node at (7.5,0.5) {$2$};
|
\node at (7.5,0.5) {$2$};
|
||||||
|
|
||||||
\draw[thick,->] (2.5,-0.25) .. controls (2.25,-1.00) and (1.75,-1.00) .. (1.6,-0.25);
|
\draw (0.2,0.2-1.2) rectangle (0.8,0.8-1.2);
|
||||||
\draw[thick,->] (1.4,-0.25) .. controls (1.25,-1.00) and (0.75,-1.00) .. (0.5,-0.25);
|
\draw (1.2,0.2-1.2) rectangle (1.8,0.8-1.2);
|
||||||
%
|
\draw (2.2,0.2-1.2) rectangle (2.8,0.8-1.2);
|
||||||
% \footnotesize
|
|
||||||
% \node at (0.5,1.4) {$1$};
|
\node at (0.5,0.5-1.2) {$1$};
|
||||||
% \node at (1.5,1.4) {$2$};
|
\node at (1.5,0.5-1.2) {$3$};
|
||||||
% \node at (2.5,1.4) {$3$};
|
\node at (2.5,0.5-1.2) {$4$};
|
||||||
% \node at (3.5,1.4) {$4$};
|
|
||||||
% \node at (4.5,1.4) {$5$};
|
\draw[->,thick] (0.8,0.5-1.2) -- (1.2,0.5-1.2);
|
||||||
% \node at (5.5,1.4) {$6$};
|
\draw[->,thick] (1.8,0.5-1.2) -- (2.2,0.5-1.2);
|
||||||
% \node at (6.5,1.4) {$7$};
|
|
||||||
% \node at (7.5,1.4) {$8$};
|
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
The next number 2 is smaller than the two first numbers in the chain.
|
The next element 2 is smaller than the two top
|
||||||
Thus, the numbers 4 and 3 are removed from the chain,
|
elements in the stack.
|
||||||
and then the number 2
|
Thus, the elements 3 and 4 are removed from the stack,
|
||||||
is added to the chain.
|
and then the element 2 is added to the stack.
|
||||||
Its nearest smaller element is 1:
|
Its nearest smaller element is 1:
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tikzpicture}[scale=0.7]
|
\begin{tikzpicture}[scale=0.7]
|
||||||
|
@ -542,22 +420,18 @@ Its nearest smaller element is 1:
|
||||||
\node at (6.5,0.5) {$4$};
|
\node at (6.5,0.5) {$4$};
|
||||||
\node at (7.5,0.5) {$2$};
|
\node at (7.5,0.5) {$2$};
|
||||||
|
|
||||||
\draw[thick,->] (3.5,-0.25) .. controls (3.00,-1.00) and (1.00,-1.00) .. (0.5,-0.25);
|
\draw (0.2,0.2-1.2) rectangle (0.8,0.8-1.2);
|
||||||
%
|
\draw (3.2,0.2-1.2) rectangle (3.8,0.8-1.2);
|
||||||
% \footnotesize
|
|
||||||
% \node at (0.5,1.4) {$1$};
|
\node at (0.5,0.5-1.2) {$1$};
|
||||||
% \node at (1.5,1.4) {$2$};
|
\node at (3.5,0.5-1.2) {$2$};
|
||||||
% \node at (2.5,1.4) {$3$};
|
|
||||||
% \node at (3.5,1.4) {$4$};
|
\draw[->,thick] (0.8,0.5-1.2) -- (3.2,0.5-1.2);
|
||||||
% \node at (4.5,1.4) {$5$};
|
|
||||||
% \node at (5.5,1.4) {$6$};
|
|
||||||
% \node at (6.5,1.4) {$7$};
|
|
||||||
% \node at (7.5,1.4) {$8$};
|
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
After this, the number 5 is larger than the number 2,
|
Then, the element 5 is larger than the element 2,
|
||||||
so it will be added to the chain, and
|
so it will be added to the stack, and
|
||||||
its nearest smaller element is 2:
|
its nearest smaller element is 2:
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tikzpicture}[scale=0.7]
|
\begin{tikzpicture}[scale=0.7]
|
||||||
|
@ -573,38 +447,90 @@ its nearest smaller element is 2:
|
||||||
\node at (6.5,0.5) {$4$};
|
\node at (6.5,0.5) {$4$};
|
||||||
\node at (7.5,0.5) {$2$};
|
\node at (7.5,0.5) {$2$};
|
||||||
|
|
||||||
\draw[thick,->] (3.4,-0.25) .. controls (3.00,-1.00) and (1.00,-1.00) .. (0.5,-0.25);
|
\draw (0.2,0.2-1.2) rectangle (0.8,0.8-1.2);
|
||||||
\draw[thick,->] (4.5,-0.25) .. controls (4.25,-1.00) and (3.75,-1.00) .. (3.6,-0.25);
|
\draw (3.2,0.2-1.2) rectangle (3.8,0.8-1.2);
|
||||||
%
|
\draw (4.2,0.2-1.2) rectangle (4.8,0.8-1.2);
|
||||||
% \footnotesize
|
|
||||||
% \node at (0.5,1.4) {$1$};
|
\node at (0.5,0.5-1.2) {$1$};
|
||||||
% \node at (1.5,1.4) {$2$};
|
\node at (3.5,0.5-1.2) {$2$};
|
||||||
% \node at (2.5,1.4) {$3$};
|
\node at (4.5,0.5-1.2) {$5$};
|
||||||
% \node at (3.5,1.4) {$4$};
|
|
||||||
% \node at (4.5,1.4) {$5$};
|
\draw[->,thick] (0.8,0.5-1.2) -- (3.2,0.5-1.2);
|
||||||
% \node at (5.5,1.4) {$6$};
|
\draw[->,thick] (3.8,0.5-1.2) -- (4.2,0.5-1.2);
|
||||||
% \node at (6.5,1.4) {$7$};
|
|
||||||
% \node at (7.5,1.4) {$8$};
|
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
The algorithm continues in the same way
|
After this, the element 5 is removed from the stack
|
||||||
and finds the nearest smaller element
|
and the elements 3 and 4 are added to the stack:
|
||||||
for each number in the array.
|
\begin{center}
|
||||||
But how efficient is the algorithm?
|
\begin{tikzpicture}[scale=0.7]
|
||||||
|
\fill[color=lightgray] (6,0) rectangle (7,1);
|
||||||
|
\draw (0,0) grid (8,1);
|
||||||
|
|
||||||
|
\node at (0.5,0.5) {$1$};
|
||||||
|
\node at (1.5,0.5) {$3$};
|
||||||
|
\node at (2.5,0.5) {$4$};
|
||||||
|
\node at (3.5,0.5) {$2$};
|
||||||
|
\node at (4.5,0.5) {$5$};
|
||||||
|
\node at (5.5,0.5) {$3$};
|
||||||
|
\node at (6.5,0.5) {$4$};
|
||||||
|
\node at (7.5,0.5) {$2$};
|
||||||
|
|
||||||
|
\draw (0.2,0.2-1.2) rectangle (0.8,0.8-1.2);
|
||||||
|
\draw (3.2,0.2-1.2) rectangle (3.8,0.8-1.2);
|
||||||
|
\draw (5.2,0.2-1.2) rectangle (5.8,0.8-1.2);
|
||||||
|
\draw (6.2,0.2-1.2) rectangle (6.8,0.8-1.2);
|
||||||
|
|
||||||
|
\node at (0.5,0.5-1.2) {$1$};
|
||||||
|
\node at (3.5,0.5-1.2) {$2$};
|
||||||
|
\node at (5.5,0.5-1.2) {$3$};
|
||||||
|
\node at (6.5,0.5-1.2) {$4$};
|
||||||
|
|
||||||
|
\draw[->,thick] (0.8,0.5-1.2) -- (3.2,0.5-1.2);
|
||||||
|
\draw[->,thick] (3.8,0.5-1.2) -- (5.2,0.5-1.2);
|
||||||
|
\draw[->,thick] (5.8,0.5-1.2) -- (6.2,0.5-1.2);
|
||||||
|
\end{tikzpicture}
|
||||||
|
\end{center}
|
||||||
|
|
||||||
|
Finally, all elements except 1 are removed
|
||||||
|
from the stack and the last element 2
|
||||||
|
is added to the stack:
|
||||||
|
|
||||||
|
\begin{center}
|
||||||
|
\begin{tikzpicture}[scale=0.7]
|
||||||
|
\fill[color=lightgray] (7,0) rectangle (8,1);
|
||||||
|
\draw (0,0) grid (8,1);
|
||||||
|
|
||||||
|
\node at (0.5,0.5) {$1$};
|
||||||
|
\node at (1.5,0.5) {$3$};
|
||||||
|
\node at (2.5,0.5) {$4$};
|
||||||
|
\node at (3.5,0.5) {$2$};
|
||||||
|
\node at (4.5,0.5) {$5$};
|
||||||
|
\node at (5.5,0.5) {$3$};
|
||||||
|
\node at (6.5,0.5) {$4$};
|
||||||
|
\node at (7.5,0.5) {$2$};
|
||||||
|
|
||||||
|
\draw (0.2,0.2-1.2) rectangle (0.8,0.8-1.2);
|
||||||
|
\draw (7.2,0.2-1.2) rectangle (7.8,0.8-1.2);
|
||||||
|
|
||||||
|
\node at (0.5,0.5-1.2) {$1$};
|
||||||
|
\node at (7.5,0.5-1.2) {$2$};
|
||||||
|
|
||||||
|
\draw[->,thick] (0.8,0.5-1.2) -- (7.2,0.5-1.2);
|
||||||
|
\end{tikzpicture}
|
||||||
|
\end{center}
|
||||||
|
|
||||||
The efficiency of the algorithm depends on
|
The efficiency of the algorithm depends on
|
||||||
the total time used for manipulating the chain.
|
the total number of stack operations.
|
||||||
If an element is larger than the first
|
If the current element is larger than
|
||||||
element of the chain, it is directly added
|
the top element in the stack, it is directly
|
||||||
to the chain, which is efficient.
|
added to the stack, which is efficient.
|
||||||
However, sometimes the chain can contain several
|
However, sometimes the stack can contain several
|
||||||
larger elements and it takes time to remove them.
|
larger elements and it takes time to remove them.
|
||||||
Still, each element is added exactly once to the chain
|
Still, each element is added \emph{exactly once} to the stack
|
||||||
and removed at most once from the chain.
|
and removed \emph{at most once} from the stack.
|
||||||
Thus, each element causes $O(1)$ chain operations,
|
Thus, each element causes $O(1)$ stack operations,
|
||||||
and the total time complexity
|
and the algorithm works in $O(n)$ time.
|
||||||
of the algorithm is $O(n)$.
|
|
||||||
|
|
||||||
\section{Sliding window minimum}
|
\section{Sliding window minimum}
|
||||||
|
|
||||||
|
@ -612,30 +538,32 @@ of the algorithm is $O(n)$.
|
||||||
\index{sliding window minimum}
|
\index{sliding window minimum}
|
||||||
|
|
||||||
A \key{sliding window} is a constant-size subarray
|
A \key{sliding window} is a constant-size subarray
|
||||||
that moves through the array.
|
that moves from left to right through the array.
|
||||||
At each position of the window,
|
At each window position,
|
||||||
we want to calculate some information
|
we want to calculate some information
|
||||||
about the elements inside the window.
|
about the elements inside the window.
|
||||||
An interesting problem is to maintain
|
In this section, we focus on the problem
|
||||||
the \key{sliding window minimum},
|
of maintaining the \key{sliding window minimum},
|
||||||
which means that at each position of the window,
|
which means that
|
||||||
we should report the smallest element inside the window.
|
we should report the smallest value inside each window.
|
||||||
|
|
||||||
The sliding window minimum can be calculated
|
The sliding window minimum can be calculated
|
||||||
using the same idea that we used for calculating
|
using a similar idea that we used to calculate
|
||||||
the nearest smaller elements.
|
the nearest smaller elements.
|
||||||
We maintain a chain whose
|
We maintain a queue
|
||||||
first element is always the last element in the window,
|
where each element is larger than
|
||||||
and each element in the chain is smaller than the previous element.
|
the previous element,
|
||||||
The last element in the chain is always the
|
and the first element
|
||||||
smallest element inside the window.
|
always corresponds to the minimum element inside the window.
|
||||||
When the sliding window moves forward and
|
After each window move,
|
||||||
a new element appears, we remove from the chain
|
we remove elements from the end of the queue
|
||||||
all elements that are larger than the new element.
|
until the last queue element
|
||||||
After this, we add the new element to the chain.
|
is smaller than the last window element,
|
||||||
Finally, if the last element in the chain
|
or the queue becomes empty.
|
||||||
does not belong to the window anymore,
|
We also remove the first queue element
|
||||||
it is removed from the chain.
|
if it is not inside the window anymore.
|
||||||
|
Finally, we add the last window element
|
||||||
|
to the end of the queue.
|
||||||
|
|
||||||
As an example, consider the following array:
|
As an example, consider the following array:
|
||||||
|
|
||||||
|
@ -651,21 +579,11 @@ As an example, consider the following array:
|
||||||
\node at (5.5,0.5) {$4$};
|
\node at (5.5,0.5) {$4$};
|
||||||
\node at (6.5,0.5) {$1$};
|
\node at (6.5,0.5) {$1$};
|
||||||
\node at (7.5,0.5) {$2$};
|
\node at (7.5,0.5) {$2$};
|
||||||
%
|
|
||||||
% \footnotesize
|
|
||||||
% \node at (0.5,1.4) {$1$};
|
|
||||||
% \node at (1.5,1.4) {$2$};
|
|
||||||
% \node at (2.5,1.4) {$3$};
|
|
||||||
% \node at (3.5,1.4) {$4$};
|
|
||||||
% \node at (4.5,1.4) {$5$};
|
|
||||||
% \node at (5.5,1.4) {$6$};
|
|
||||||
% \node at (6.5,1.4) {$7$};
|
|
||||||
% \node at (7.5,1.4) {$8$};
|
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
Suppose that the size of the sliding window is 4.
|
Suppose that the size of the sliding window is 4.
|
||||||
At the first window position, the smallest element is 1:
|
At the first window position, the smallest value is 1:
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tikzpicture}[scale=0.7]
|
\begin{tikzpicture}[scale=0.7]
|
||||||
\fill[color=lightgray] (0,0) rectangle (4,1);
|
\fill[color=lightgray] (0,0) rectangle (4,1);
|
||||||
|
@ -679,29 +597,26 @@ At the first window position, the smallest element is 1:
|
||||||
\node at (5.5,0.5) {$4$};
|
\node at (5.5,0.5) {$4$};
|
||||||
\node at (6.5,0.5) {$1$};
|
\node at (6.5,0.5) {$1$};
|
||||||
\node at (7.5,0.5) {$2$};
|
\node at (7.5,0.5) {$2$};
|
||||||
%
|
|
||||||
% \footnotesize
|
|
||||||
% \node at (0.5,1.4) {$1$};
|
|
||||||
% \node at (1.5,1.4) {$2$};
|
|
||||||
% \node at (2.5,1.4) {$3$};
|
|
||||||
% \node at (3.5,1.4) {$4$};
|
|
||||||
% \node at (4.5,1.4) {$5$};
|
|
||||||
% \node at (5.5,1.4) {$6$};
|
|
||||||
% \node at (6.5,1.4) {$7$};
|
|
||||||
% \node at (7.5,1.4) {$8$};
|
|
||||||
|
|
||||||
\draw[thick,->] (3.5,-0.25) .. controls (3.25,-1.00) and (2.75,-1.00) .. (2.6,-0.25);
|
\draw (1.2,0.2-1.2) rectangle (1.8,0.8-1.2);
|
||||||
\draw[thick,->] (2.4,-0.25) .. controls (2.25,-1.00) and (1.75,-1.00) .. (1.5,-0.25);
|
\draw (2.2,0.2-1.2) rectangle (2.8,0.8-1.2);
|
||||||
|
\draw (3.2,0.2-1.2) rectangle (3.8,0.8-1.2);
|
||||||
|
|
||||||
|
\node at (1.5,0.5-1.2) {$1$};
|
||||||
|
\node at (2.5,0.5-1.2) {$4$};
|
||||||
|
\node at (3.5,0.5-1.2) {$5$};
|
||||||
|
|
||||||
|
\draw[->,thick] (1.8,0.5-1.2) -- (2.2,0.5-1.2);
|
||||||
|
\draw[->,thick] (2.8,0.5-1.2) -- (3.2,0.5-1.2);
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
Then the window moves one step forward.
|
Then the window moves one step right.
|
||||||
The new number 3 is smaller than the numbers
|
The new element 3 is smaller than the elements
|
||||||
5 and 4 in the chain, so the numbers 5 and 4
|
4 and 5 in the queue, so the elements 4 and 5
|
||||||
are removed from the chain
|
are removed from the queue
|
||||||
and the number 3 is added to the chain.
|
and the element 3 is added to the queue.
|
||||||
The smallest element is still 1.
|
The smallest value is still 1.
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tikzpicture}[scale=0.7]
|
\begin{tikzpicture}[scale=0.7]
|
||||||
\fill[color=lightgray] (1,0) rectangle (5,1);
|
\fill[color=lightgray] (1,0) rectangle (5,1);
|
||||||
|
@ -715,28 +630,23 @@ The smallest element is still 1.
|
||||||
\node at (5.5,0.5) {$4$};
|
\node at (5.5,0.5) {$4$};
|
||||||
\node at (6.5,0.5) {$1$};
|
\node at (6.5,0.5) {$1$};
|
||||||
\node at (7.5,0.5) {$2$};
|
\node at (7.5,0.5) {$2$};
|
||||||
%
|
|
||||||
% \footnotesize
|
|
||||||
% \node at (0.5,1.4) {$1$};
|
|
||||||
% \node at (1.5,1.4) {$2$};
|
|
||||||
% \node at (2.5,1.4) {$3$};
|
|
||||||
% \node at (3.5,1.4) {$4$};
|
|
||||||
% \node at (4.5,1.4) {$5$};
|
|
||||||
% \node at (5.5,1.4) {$6$};
|
|
||||||
% \node at (6.5,1.4) {$7$};
|
|
||||||
% \node at (7.5,1.4) {$8$};
|
|
||||||
|
|
||||||
\draw[thick,->] (4.5,-0.25) .. controls (4.25,-1.00) and (1.75,-1.00) .. (1.5,-0.25);
|
\draw (1.2,0.2-1.2) rectangle (1.8,0.8-1.2);
|
||||||
|
\draw (4.2,0.2-1.2) rectangle (4.8,0.8-1.2);
|
||||||
|
|
||||||
|
\node at (1.5,0.5-1.2) {$1$};
|
||||||
|
\node at (4.5,0.5-1.2) {$3$};
|
||||||
|
|
||||||
|
\draw[->,thick] (1.8,0.5-1.2) -- (4.2,0.5-1.2);
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
After this, the window moves again,
|
After this, the window moves again,
|
||||||
and the smallest element 1
|
and the smallest element 1
|
||||||
does not belong to the window anymore.
|
does not belong to the window anymore.
|
||||||
Thus, it is removed from the chain and the smallest
|
Thus, it is removed from the queue and the smallest
|
||||||
element is now 3. In addition, the new number 4
|
value is now 3. Also the new element 4
|
||||||
is added to the chain.
|
is added to the queue.
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tikzpicture}[scale=0.7]
|
\begin{tikzpicture}[scale=0.7]
|
||||||
\fill[color=lightgray] (2,0) rectangle (6,1);
|
\fill[color=lightgray] (2,0) rectangle (6,1);
|
||||||
|
@ -750,24 +660,20 @@ is added to the chain.
|
||||||
\node at (5.5,0.5) {$4$};
|
\node at (5.5,0.5) {$4$};
|
||||||
\node at (6.5,0.5) {$1$};
|
\node at (6.5,0.5) {$1$};
|
||||||
\node at (7.5,0.5) {$2$};
|
\node at (7.5,0.5) {$2$};
|
||||||
%
|
|
||||||
% \footnotesize
|
|
||||||
% \node at (0.5,1.4) {$1$};
|
|
||||||
% \node at (1.5,1.4) {$2$};
|
|
||||||
% \node at (2.5,1.4) {$3$};
|
|
||||||
% \node at (3.5,1.4) {$4$};
|
|
||||||
% \node at (4.5,1.4) {$5$};
|
|
||||||
% \node at (5.5,1.4) {$6$};
|
|
||||||
% \node at (6.5,1.4) {$7$};
|
|
||||||
% \node at (7.5,1.4) {$8$};
|
|
||||||
|
|
||||||
\draw[thick,->] (5.5,-0.25) .. controls (5.25,-1.00) and (4.75,-1.00) .. (4.5,-0.25);
|
\draw (4.2,0.2-1.2) rectangle (4.8,0.8-1.2);
|
||||||
|
\draw (5.2,0.2-1.2) rectangle (5.8,0.8-1.2);
|
||||||
|
|
||||||
|
\node at (4.5,0.5-1.2) {$3$};
|
||||||
|
\node at (5.5,0.5-1.2) {$4$};
|
||||||
|
|
||||||
|
\draw[->,thick] (4.8,0.5-1.2) -- (5.2,0.5-1.2);
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
The next new element 1 is smaller than all elements
|
The next new element 1 is smaller than all elements
|
||||||
in the chain.
|
in the queue.
|
||||||
Thus, all elements are removed from the chain
|
Thus, all elements are removed from the queue
|
||||||
and it will only contain the element 1:
|
and it will only contain the element 1:
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tikzpicture}[scale=0.7]
|
\begin{tikzpicture}[scale=0.7]
|
||||||
|
@ -782,26 +688,16 @@ and it will only contain the element 1:
|
||||||
\node at (5.5,0.5) {$4$};
|
\node at (5.5,0.5) {$4$};
|
||||||
\node at (6.5,0.5) {$1$};
|
\node at (6.5,0.5) {$1$};
|
||||||
\node at (7.5,0.5) {$2$};
|
\node at (7.5,0.5) {$2$};
|
||||||
%
|
|
||||||
% \footnotesize
|
|
||||||
% \node at (0.5,1.4) {$1$};
|
|
||||||
% \node at (1.5,1.4) {$2$};
|
|
||||||
% \node at (2.5,1.4) {$3$};
|
|
||||||
% \node at (3.5,1.4) {$4$};
|
|
||||||
% \node at (4.5,1.4) {$5$};
|
|
||||||
% \node at (5.5,1.4) {$6$};
|
|
||||||
% \node at (6.5,1.4) {$7$};
|
|
||||||
% \node at (7.5,1.4) {$8$};
|
|
||||||
|
|
||||||
\fill[color=black] (6.5,-0.25) circle (0.1);
|
\draw (6.2,0.2-1.2) rectangle (6.8,0.8-1.2);
|
||||||
|
|
||||||
%\draw[thick,->] (5.5,-0.25) .. controls (5.25,-1.00) and (4.75,-1.00) .. (4.5,-0.25);
|
\node at (6.5,0.5-1.2) {$1$};
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
Finally the window reaches its last position.
|
Finally the window reaches its last position.
|
||||||
The number 2 is added to the chain,
|
The element 2 is added to the queue,
|
||||||
but the smallest element inside the window
|
but the smallest value inside the window
|
||||||
is still 1.
|
is still 1.
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tikzpicture}[scale=0.7]
|
\begin{tikzpicture}[scale=0.7]
|
||||||
|
@ -816,25 +712,21 @@ is still 1.
|
||||||
\node at (5.5,0.5) {$4$};
|
\node at (5.5,0.5) {$4$};
|
||||||
\node at (6.5,0.5) {$1$};
|
\node at (6.5,0.5) {$1$};
|
||||||
\node at (7.5,0.5) {$2$};
|
\node at (7.5,0.5) {$2$};
|
||||||
%
|
|
||||||
% \footnotesize
|
|
||||||
% \node at (0.5,1.4) {$1$};
|
|
||||||
% \node at (1.5,1.4) {$2$};
|
|
||||||
% \node at (2.5,1.4) {$3$};
|
|
||||||
% \node at (3.5,1.4) {$4$};
|
|
||||||
% \node at (4.5,1.4) {$5$};
|
|
||||||
% \node at (5.5,1.4) {$6$};
|
|
||||||
% \node at (6.5,1.4) {$7$};
|
|
||||||
% \node at (7.5,1.4) {$8$};
|
|
||||||
|
|
||||||
\draw[thick,->] (7.5,-0.25) .. controls (7.25,-1.00) and (6.75,-1.00) .. (6.5,-0.25);
|
\draw (6.2,0.2-1.2) rectangle (6.8,0.8-1.2);
|
||||||
|
\draw (7.2,0.2-1.2) rectangle (7.8,0.8-1.2);
|
||||||
|
|
||||||
|
\node at (6.5,0.5-1.2) {$1$};
|
||||||
|
\node at (7.5,0.5-1.2) {$2$};
|
||||||
|
|
||||||
|
\draw[->,thick] (6.8,0.5-1.2) -- (7.2,0.5-1.2);
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
Also in this algorithm, each element in the array
|
Since each array element
|
||||||
is added to the chain exactly once and
|
is added to the queue exactly once and
|
||||||
removed from the chain at most once.
|
removed from the queue at most once,
|
||||||
Thus, the total time complexity of the algorithm is $O(n)$.
|
the algorithm works in $O(n)$ time.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue