diff --git a/luku08.tex b/luku08.tex index 482b20e..b2f96d1 100644 --- a/luku08.tex +++ b/luku08.tex @@ -1,41 +1,42 @@ \chapter{Amortized analysis} -\index{tasoitettu analyysi@tasoitettu analyysi} +\index{amortized analysis} -Monen algoritmin aikavaativuuden pystyy laskemaan -suoraan katsomalla algoritmin rakennetta: -mitä silmukoita algoritmissa on ja miten monta -kertaa niitä suoritetaan. -Joskus kuitenkaan näin suoraviivainen analyysi ei -riitä antamaan todellista kuvaa algoritmin tehokkuudesta. +Often the time complexity of an algorithm +is easy to analyze by looking at the structure +of the algorithm: +what loops there are and how many times +they are performed. +However, sometimes a straightforward analysis +doesn't give a true picture of the efficiency of the algorithm. -\key{Tasoitettu analyysi} soveltuu sellaisten -algoritmien analyysiin, joiden osana on jokin operaatio, -jonka ajankäyttö vaihtelee. -Ideana on tarkastella yksittäisen operaation -sijasta kaikkia operaatioita algoritmin -aikana ja laskea niiden ajankäytölle yhteinen raja. +\key{Amortized analysis} can be used for analyzing +an algorithm that contains an operation whose +time complexity varies. +The idea is to consider all such operations during the +execution of the algorithm instead of a single operation, +and estimate the total time complexity of the operations. -\section{Kahden osoittimen tekniikka} +\section{Two pointers method} -\index{kahden osoittimen tekniikka} +\index{two pointers method} -\key{Kahden osoittimen tekniikka} on taulukon käsittelyssä -käytettävä menetelmä, jossa taulukkoa käydään läpi -kahden osoittimen avulla. -Molemmat osoittimet liikkuvat algoritmin aikana, -mutta rajoituksena on, että ne voivat liikkua vain -yhteen suuntaan, mikä takaa, että algoritmi toimii tehokkaasti. +In the \key{two pointers method}, +two pointers iterate through the elements in an array. +Both pointers can move during the algorithm, +but the restriction is that each pointer can move +to only one direction. +This ensures that the algorithm works efficiently. -Tutustumme seuraavaksi kahden osoittimen tekniikkaan -kahden esimerkkitehtävän kautta. +We will next discuss two problems that can be solved +using the two pointers method. -\subsubsection{Alitaulukon summa} +\subsubsection{Subarray sum} -Annettuna on taulukko, jossa on $n$ positiivista kokonaislukua. -Tehtävänä on selvittää, onko taulukossa alitaulukkoa, -jossa lukujen summa on $x$. -Esimerkiksi taulukossa +Given an array that contains $n$ positive integers, +our task is to find out if there is a subarray +where the sum of the elements is $x$. +For example, the array \begin{center} \begin{tikzpicture}[scale=0.7] \draw (0,0) grid (8,1); @@ -60,7 +61,7 @@ Esimerkiksi taulukossa \node at (7.5,1.4) {$8$}; \end{tikzpicture} \end{center} -on alitaulukko, jossa lukujen summa on 8: +contains a subarray with sum 8: \begin{center} \begin{tikzpicture}[scale=0.7] \fill[color=lightgray] (2,0) rectangle (5,1); @@ -87,17 +88,18 @@ on alitaulukko, jossa lukujen summa on 8: \end{tikzpicture} \end{center} -Osoittautuu, että tämän tehtävän voi ratkaista -ajassa $O(n)$ kahden osoittimen tekniikalla. -Ideana on käydä taulukkoa läpi kahden osoittimen -avulla, jotka rajaavat välin taulukosta. -Joka vuorolla vasen osoitin liikkuu -yhden askeleen eteenpäin ja oikea osoitin -liikkuu niin kauan eteenpäin kuin summa on enintään $x$. -Jos välin summaksi tulee tarkalleen $x$, ratkaisu on löytynyt. +It turns out that the problem can be solved in +$O(n)$ time using the two pointers method. +The idea is to iterate through the array +using two pointers that define a range in the array. +On each turn, the left pointer moves one step +forward, and the right pointer moves forward +as long as the sum is at most $x$. +If the sum of the range becomes exactly $x$, +we have found a solution. -Tarkastellaan esimerkkinä algoritmin toimintaa -seuraavassa taulukossa, kun tavoitteena on muodostaa summa $x=8$: +As an example, we consider the following array +with target sum $x=8$: \begin{center} \begin{tikzpicture}[scale=0.7] \draw (0,0) grid (8,1); @@ -123,10 +125,10 @@ seuraavassa taulukossa, kun tavoitteena on muodostaa summa $x=8$: \end{tikzpicture} \end{center} -Aluksi osoittimet rajaavat taulukosta välin, -jonka summa on $1+3+2=6$. -Väli ei voi olla tätä suurempi, -koska seuraava luku 5 veisi summan yli $x$:n. +First, the pointers define a range with sum $1+3+2=6$. +The range can't be larger +because the next number 5 would make the sum +larger than $x$. \begin{center} \begin{tikzpicture}[scale=0.7] @@ -157,9 +159,9 @@ koska seuraava luku 5 veisi summan yli $x$:n. \end{tikzpicture} \end{center} -Seuraavaksi vasen osoitin siirtyy askeleen eteenpäin. -Oikea osoitin säilyy paikallaan, koska muuten -summa kasvaisi liian suureksi. +After this, the left pointer moves one step forward. +The right pointer doesn't move because otherwise +the sum would become too large. \begin{center} \begin{tikzpicture}[scale=0.7] @@ -190,10 +192,11 @@ summa kasvaisi liian suureksi. \end{tikzpicture} \end{center} -Vasen osoitin siirtyy taas askeleen eteenpäin -ja tällä kertaa oikea osoitin siirtyy kolme askelta -eteenpäin. Muodostuu summa $2+5+1=8$ eli taulukosta -on löytynyt väli, jonka lukujen summa on $x$. +Again, the left pointer moves one step forward, +and this time the right pointer moves three +steps forward. +The sum is $2+5+1=8$, so we have found a subarray +where the sum of the elements is $x$. \begin{center} \begin{tikzpicture}[scale=0.7] @@ -224,67 +227,42 @@ on löytynyt väli, jonka lukujen summa on $x$. \end{tikzpicture} \end{center} -% Algoritmin toteutus näyttää seuraavalta: -% -% \begin{lstlisting} -% int s = 0, b = 0; -% for (int a = 1; a <= n; a++) { -% while (b