Nearest smaller elements
This commit is contained in:
parent
7f443cd64e
commit
173e5e75dd
118
luku08.tex
118
luku08.tex
|
@ -413,41 +413,44 @@ to find \emph{three} numbers whose sum is $x$.
|
||||||
This problem can be solved in $O(n^2)$ time.
|
This problem can be solved in $O(n^2)$ time.
|
||||||
Can you see how it is possible?
|
Can you see how it is possible?
|
||||||
|
|
||||||
\section{Lähin pienempi edeltäjä}
|
\section{Nearest smaller elements}
|
||||||
|
|
||||||
\index{lzhin pienempi edeltxjx@lähin pienempi edeltäjä}
|
\index{nearest smaller elements}
|
||||||
|
|
||||||
Tasoitetun analyysin avulla arvioidaan usein
|
Amortized analysis is often used for
|
||||||
tietorakenteeseen kohdistuvien operaatioiden määrää.
|
estimating the number of operations
|
||||||
Algoritmin operaatiot voivat jakautua epätasaisesti
|
performed for a data structure.
|
||||||
niin, että useimmat operaatiot tehdään tietyssä
|
The operations may be distributed unevenly so
|
||||||
algoritmin vaiheessa, mutta operaatioiden
|
that the most operations appear during a
|
||||||
yhteismäärä on kuitenkin rajoitettu.
|
certain phase in the algorithm, but the total
|
||||||
|
number of the operations is limited.
|
||||||
|
|
||||||
Tarkastellaan esimerkkinä ongelmaa,
|
As an example, let us consider a problem
|
||||||
jossa tehtävänä on etsiä kullekin taulukon
|
where our task is to find for each element
|
||||||
alkiolle
|
in an array the
|
||||||
\key{lähin pienempi edeltäjä} eli
|
\key{nearest smaller element}, i.e.,
|
||||||
lähinnä oleva pienempi alkio taulukon alkuosassa.
|
the nearest smaller element that precedes
|
||||||
On mahdollista, ettei tällaista alkiota ole olemassa,
|
the element in the array.
|
||||||
jolloin algoritmin tulee huomata asia.
|
It is possible that no such element exists,
|
||||||
Osoittautuu, että tehtävä on mahdollista ratkaista
|
and the algorithm should notice this.
|
||||||
tehokkaasti ajassa $O(n)$ sopivan tietorakenteen avulla.
|
It turns out that the problem can be efficiently solved
|
||||||
|
in $O(n)$ time using a suitable data structure.
|
||||||
|
|
||||||
Tehokas ratkaisu tehtävään on käydä
|
An efficient solution for the problem is to
|
||||||
taulukko läpi alusta loppuun ja pitää samalla yllä ketjua,
|
iterate through the array from the left to the right,
|
||||||
jonka ensimmäinen luku on käsiteltävä taulukon luku
|
and maintain a chain of elements where the
|
||||||
ja jokainen seuraava luku on luvun lähin
|
first element is the active element in the array
|
||||||
pienempi edeltäjä.
|
and each following element is the nearest smaller
|
||||||
Jos ketjussa on vain yksi luku,
|
element of the previous element.
|
||||||
käsiteltävällä luvulla ei ole pienempää edeltäjää.
|
If the chain only contains one element,
|
||||||
Joka askeleella ketjun alusta poistetaan lukuja
|
the active element doesn't have a nearest smaller element.
|
||||||
niin kauan, kunnes ketjun ensimmäinen luku on
|
At each step, we remove elements from the chain
|
||||||
pienempi kuin käsiteltävä taulukon luku tai ketju on tyhjä.
|
until the first element is smaller
|
||||||
Tämän jälkeen käsiteltävä luku lisätään ketjun alkuun.
|
than the active element, or the chain is empty.
|
||||||
|
After this, the active element becomes the first element
|
||||||
|
in the chain.
|
||||||
|
|
||||||
Tarkastellaan esimerkkinä algoritmin toimintaa
|
As an example, consider the following array:
|
||||||
seuraavassa taulukossa:
|
|
||||||
\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);
|
||||||
|
@ -473,9 +476,11 @@ seuraavassa taulukossa:
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
Aluksi luvut 1, 3 ja 4 liittyvät ketjuun, koska jokainen luku on
|
First, numbers 1, 3 and 4 are added to the chain
|
||||||
edellistä suurempi. Siis luvun 4 lähin pienempi edeltäjä on luku 3,
|
because each element is larger than the previous element.
|
||||||
jonka lähin pienempi edeltäjä on puolestaan luku 1. Tilanne näyttää tältä:
|
This means that the nearest smaller element of
|
||||||
|
number 4 is number 3 whose nearest smaller element
|
||||||
|
is number 1.
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tikzpicture}[scale=0.7]
|
\begin{tikzpicture}[scale=0.7]
|
||||||
\fill[color=lightgray] (2,0) rectangle (3,1);
|
\fill[color=lightgray] (2,0) rectangle (3,1);
|
||||||
|
@ -505,9 +510,10 @@ jonka lähin pienempi edeltäjä on puolestaan luku 1. Tilanne näyttää tält
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
Taulukon seuraava luku 2 on pienempi kuin ketjun kaksi ensimmäistä lukua 4 ja 3.
|
The next number 2 is smaller than two first numbers in the chain.
|
||||||
Niinpä luvut 4 ja 3 poistetaan ketjusta, minkä jälkeen luku 2
|
Thus, numbers 4 and 3 are removed, and then number 2 becomes
|
||||||
lisätään ketjun alkuun. Sen lähin pienempi edeltäjä on luku 1:
|
the first element in the chain.
|
||||||
|
Its nearest smaller element is number 1:
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tikzpicture}[scale=0.7]
|
\begin{tikzpicture}[scale=0.7]
|
||||||
\fill[color=lightgray] (3,0) rectangle (4,1);
|
\fill[color=lightgray] (3,0) rectangle (4,1);
|
||||||
|
@ -536,9 +542,9 @@ lisätään ketjun alkuun. Sen lähin pienempi edeltäjä on luku 1:
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
Seuraava luku 5 on suurempi kuin luku 2,
|
After this, number 5 is larger than number 2,
|
||||||
joten se lisätään suoraan ketjun alkuun ja
|
so it will be added to the chain and
|
||||||
sen lähin pienempi edeltäjä on luku 2:
|
its nearest smaller element is number 2:
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tikzpicture}[scale=0.7]
|
\begin{tikzpicture}[scale=0.7]
|
||||||
\fill[color=lightgray] (4,0) rectangle (5,1);
|
\fill[color=lightgray] (4,0) rectangle (5,1);
|
||||||
|
@ -568,25 +574,23 @@ sen lähin pienempi edeltäjä on luku 2:
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
Algoritmi jatkaa samalla tavalla taulukon loppuun
|
Algorithm continues in a similar way
|
||||||
ja selvittää jokaisen luvun lähimmän
|
and finds out the nearest smaller element
|
||||||
pienemmän edeltäjän.
|
for each number in the array.
|
||||||
Mutta kuinka tehokas algoritmi on?
|
But how efficient is the algorithm?
|
||||||
|
|
||||||
Algoritmin tehokkuus riippuu siitä,
|
The efficiency of the algorithm depends on
|
||||||
kauanko ketjun käsittelyyn kuluu aikaa yhteensä.
|
the total time used for manipulating the chain.
|
||||||
Jos uusi luku on suurempi kuin ketjun ensimmäinen
|
If an element is larger than the first
|
||||||
luku, se vain lisätään ketjun alkuun,
|
element in the chain, it will only be inserted
|
||||||
mikä on tehokasta.
|
to the beginning of the chain which is efficient.
|
||||||
Joskus taas ketjussa voi olla useita
|
However, sometimes the chain can contain several
|
||||||
suurempia lukuja, joiden poistaminen vie aikaa.
|
larger elements and it takes time to remove them.
|
||||||
Oleellista on kuitenkin, että jokainen
|
Still, each element is added exactly once to the chain
|
||||||
taulukossa oleva luku liittyy
|
and removed at most once.
|
||||||
tarkalleen kerran ketjuun ja poistuu
|
Thus, each element causes $O(1)$ operations
|
||||||
korkeintaan kerran ketjusta.
|
to the chain, and the total time complexity
|
||||||
Niinpä jokainen luku aiheuttaa $O(1)$
|
of the algorithm is $O(n)$.
|
||||||
ketjuun liittyvää operaatiota
|
|
||||||
ja algoritmin kokonaisaikavaativuus on $O(n)$.
|
|
||||||
|
|
||||||
\section{Liukuvan ikkunan minimi}
|
\section{Liukuvan ikkunan minimi}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue