diff --git a/chapter02.tex b/chapter02.tex index 56f12d6..d0f0c4b 100644 --- a/chapter02.tex +++ b/chapter02.tex @@ -354,12 +354,12 @@ However, by designing a better algorithm, it is possible to solve the problem in $O(n^2)$ time and even in $O(n)$ time. -Given an array of $n$ integers $x_1,x_2,\ldots,x_n$, -our task is to find the -\key{maximum subarray sum}\footnote{J. Bentley's -book \emph{Programming Pearls} \cite{ben86} made the problem popular.}, i.e., +Given an array of $n$ numbers, +our task is to calculate the +\key{maximum subarray sum}, i.e., the largest possible sum of numbers -in a contiguous region in the array. +in a contiguous region in the array\footnote{J. Bentley's +book \emph{Programming Pearls} \cite{ben86} made the problem popular.}. The problem is interesting when there may be negative numbers in the array. For example, in the array @@ -375,16 +375,6 @@ For example, in the array \node at (5.5,0.5) {$2$}; \node at (6.5,0.5) {$-5$}; \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{center} \begin{samepage} @@ -402,23 +392,15 @@ the following subarray produces the maximum sum $10$: \node at (5.5,0.5) {$2$}; \node at (6.5,0.5) {$-5$}; \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{center} \end{samepage} \subsubsection{Algorithm 1} -A straightforward algorithm to solve the problem +Let us assume that the numbers are stored in +an array \texttt{x}. +A straightforward way to solve the problem is to go through all possible ways of selecting a subarray, calculate the sum of the numbers in each subarray and maintain @@ -427,8 +409,8 @@ The following code implements this algorithm: \begin{lstlisting} int p = 0; -for (int a = 1; a <= n; a++) { - for (int b = a; b <= n; b++) { +for (int a = 0; a < n; a++) { + for (int b = a; b < n; b++) { int s = 0; for (int c = a; c <= b; c++) { s += x[c]; @@ -439,8 +421,6 @@ for (int a = 1; a <= n; a++) { cout << p << "\n"; \end{lstlisting} -The code assumes that the numbers are stored in an array \texttt{x} -with indices $1 \ldots n$. The variables $a$ and $b$ determine the first and last number in the subarray, and the sum of the numbers is calculated to the variable $s$. @@ -460,9 +440,9 @@ The result is the following code: \begin{lstlisting} int p = 0; -for (int a = 1; a <= n; a++) { +for (int a = 0; a < n; a++) { int s = 0; - for (int b = a; b <= n; b++) { + for (int b = a; b < n; b++) { s += x[b]; p = max(p,s); } @@ -502,7 +482,7 @@ for each ending position from left to right. The following code implements the algorithm: \begin{lstlisting} int p = 0, s = 0; -for (int k = 1; k <= n; k++) { +for (int k = 0; k < n; k++) { s = max(x[k],s+x[k]); p = max(p,s); } diff --git a/chapter03.tex b/chapter03.tex index 5516efe..0d4391c 100644 --- a/chapter03.tex +++ b/chapter03.tex @@ -49,15 +49,15 @@ For example, the array \node at (6.5,0.5) {$5$}; \node at (7.5,0.5) {$6$}; -\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$}; +% \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{center} will be as follows after sorting: @@ -73,15 +73,15 @@ will be as follows after sorting: \node at (6.5,0.5) {$8$}; \node at (7.5,0.5) {$9$}; -\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$}; +% \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{center} @@ -97,18 +97,17 @@ A famous $O(n^2)$ time sorting algorithm is \key{bubble sort} where the elements ''bubble'' in the array according to their values. -Bubble sort consists of $n-1$ rounds. +Bubble sort consists of $n$ rounds. On each round, the algorithm iterates through the elements of the array. Whenever two consecutive elements are found that are not in correct order, the algorithm swaps them. The algorithm can be implemented as follows -for an array -$\texttt{t}[1],\texttt{t}[2],\ldots,\texttt{t}[n]$: +for an array \texttt{x}: \begin{lstlisting} -for (int i = 1; i <= n-1; i++) { - for (int j = 1; j <= n-i; j++) { +for (int i = 0; i < n; i++) { + for (int j = 0; j < n-1; j++) { if (t[j] > t[j+1]) swap(t[j],t[j+1]); } } @@ -118,7 +117,7 @@ After the first round of the algorithm, the largest element will be in the correct position, and in general, after $k$ rounds, the $k$ largest elements will be in the correct positions. -Thus, after $n-1$ rounds, the whole array +Thus, after $n$ rounds, the whole array will be sorted. For example, in the array @@ -135,16 +134,16 @@ For example, in the array \node at (5.5,0.5) {$2$}; \node at (6.5,0.5) {$5$}; \node at (7.5,0.5) {$6$}; - -\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$}; +% +% \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{center} @@ -165,16 +164,16 @@ as follows: \node at (7.5,0.5) {$6$}; \draw[thick,<->] (3.5,-0.25) .. controls (3.25,-1.00) and (2.75,-1.00) .. (2.5,-0.25); - -\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$}; +% +% \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{center} @@ -191,17 +190,16 @@ as follows: \node at (7.5,0.5) {$6$}; \draw[thick,<->] (5.5,-0.25) .. controls (5.25,-1.00) and (4.75,-1.00) .. (4.5,-0.25); - - -\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$}; +% +% \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{center} @@ -218,17 +216,16 @@ as follows: \node at (7.5,0.5) {$6$}; \draw[thick,<->] (6.5,-0.25) .. controls (6.25,-1.00) and (5.75,-1.00) .. (5.5,-0.25); - - -\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$}; +% +% \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{center} @@ -245,16 +242,16 @@ as follows: \node at (7.5,0.5) {$9$}; \draw[thick,<->] (7.5,-0.25) .. controls (7.25,-1.00) and (6.75,-1.00) .. (6.5,-0.25); - -\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$}; +% +% \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{center} @@ -289,16 +286,16 @@ For example, in the array \node at (5.5,0.5) {$5$}; \node at (6.5,0.5) {$9$}; \node at (7.5,0.5) {$8$}; - -\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$}; +% +% \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{center} the inversions are $(6,3)$, $(6,5)$ and $(9,8)$. @@ -360,16 +357,16 @@ For example, consider sorting the following array: \node at (5.5,0.5) {$2$}; \node at (6.5,0.5) {$5$}; \node at (7.5,0.5) {$9$}; - -\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$}; +% +% \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{center} @@ -389,16 +386,16 @@ as follows: \node at (6.5,0.5) {$2$}; \node at (7.5,0.5) {$5$}; \node at (8.5,0.5) {$9$}; - -\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 (5.5,1.4) {$5$}; -\node at (6.5,1.4) {$6$}; -\node at (7.5,1.4) {$7$}; -\node at (8.5,1.4) {$8$}; +% +% \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 (5.5,1.4) {$5$}; +% \node at (6.5,1.4) {$6$}; +% \node at (7.5,1.4) {$7$}; +% \node at (8.5,1.4) {$8$}; \end{tikzpicture} \end{center} @@ -419,16 +416,16 @@ as follows: \node at (6.5,0.5) {$5$}; \node at (7.5,0.5) {$8$}; \node at (8.5,0.5) {$9$}; - -\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 (5.5,1.4) {$5$}; -\node at (6.5,1.4) {$6$}; -\node at (7.5,1.4) {$7$}; -\node at (8.5,1.4) {$8$}; +% +% \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 (5.5,1.4) {$5$}; +% \node at (6.5,1.4) {$6$}; +% \node at (7.5,1.4) {$7$}; +% \node at (8.5,1.4) {$8$}; \end{tikzpicture} \end{center} @@ -445,16 +442,16 @@ subarrays and creates the final sorted array: \node at (5.5,0.5) {$6$}; \node at (6.5,0.5) {$8$}; \node at (7.5,0.5) {$9$}; - -\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$}; +% +% \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{center} @@ -546,6 +543,7 @@ whose indices are elements in the original array. The algorithm iterates through the original array and calculates how many times each element appears in the array. +\newpage For example, the array \begin{center} @@ -559,16 +557,16 @@ For example, the array \node at (5.5,0.5) {$3$}; \node at (6.5,0.5) {$5$}; \node at (7.5,0.5) {$9$}; - -\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$}; +% +% \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{center} corresponds to the following bookkeeping array: @@ -658,6 +656,7 @@ int n = 7; // array size int t[] = {4,2,5,3,5,8,3}; sort(t,t+n); \end{lstlisting} +\newpage The following code sorts the string \texttt{s}: \begin{lstlisting} string s = "monkey"; @@ -776,7 +775,7 @@ For example, the following code searches for an element $x$ in the array \texttt{t}: \begin{lstlisting} -for (int i = 1; i <= n; i++) { +for (int i = 0; i < n; i++) { if (t[i] == x) {} // x found at index i } \end{lstlisting} @@ -815,7 +814,7 @@ depending on the value of the middle element. The above idea can be implemented as follows: \begin{lstlisting} -int a = 1, b = n; +int a = 0, b = n-1; while (a <= b) { int k = (a+b)/2; if (t[k] == x) {} // x found at index k @@ -848,9 +847,9 @@ been found or we know that it does not appear in the array. The following code implements the above idea: \begin{lstlisting} -int k = 1; +int k = 0; for (int b = n/2; b >= 1; b /= 2) { - while (k+b <= n && t[k+b] <= x) k += b; + while (k+b < n && t[k+b] <= x) k += b; } if (t[k] == x) {} // x was found at index k \end{lstlisting} diff --git a/chapter05.tex b/chapter05.tex index 0dff6a6..d2f21e4 100644 --- a/chapter05.tex +++ b/chapter05.tex @@ -22,9 +22,9 @@ dynamic programming, may be needed. We first consider the problem of generating all subsets of a set of $n$ elements. -For example, the subsets of $\{1,2,3\}$ are -$\emptyset$, $\{1\}$, $\{2\}$, $\{3\}$, $\{1,2\}$, -$\{1,3\}$, $\{2,3\}$ and $\{1,2,3\}$. +For example, the subsets of $\{0,1,2\}$ are +$\emptyset$, $\{0\}$, $\{1\}$, $\{2\}$, $\{0,1\}$, +$\{0,2\}$, $\{1,2\}$ and $\{0,1,2\}$. There are two common methods for this: we can either implement a recursive search or use bit operations of integers. @@ -35,21 +35,21 @@ An elegant way to go through all subsets of a set is to use recursion. The following function generates the subsets of the set -$\{1,2,\ldots,n\}$. -The function maintains a vector \texttt{v} +$\{0,1,\ldots,n-1\}$. +The function maintains a vector \texttt{subset} that will contain the elements of each subset. The search begins when the function is called -with parameter 1. +with parameter 0. \begin{lstlisting} void gen(int k) { - if (k == n+1) { - // process subset v + if (k == n) { + // process subset } else { gen(k+1); - v.push_back(k); + subset.push_back(k); gen(k+1); - v.pop_back(); + subset.pop_back(); } } \end{lstlisting} @@ -59,7 +59,7 @@ candidate to be included in the subset. The function considers two cases that both generate a recursive call: either $k$ is included or not included in the subset. -Finally, when $k=n+1$, all elements have been processed +Finally, when $k=n$, all elements have been processed and one subset has been generated. The following tree illustrates how the function is @@ -72,41 +72,41 @@ We can always choose either the left branch \begin{tikzpicture}[scale=.45] \begin{scope} \small - \node at (0,0) {$\texttt{gen}(1)$}; + \node at (0,0) {$\texttt{gen}(0)$}; - \node at (-8,-4) {$\texttt{gen}(2)$}; - \node at (8,-4) {$\texttt{gen}(2)$}; + \node at (-8,-4) {$\texttt{gen}(1)$}; + \node at (8,-4) {$\texttt{gen}(1)$}; \path[draw,thick,->] (0,0-0.5) -- (-8,-4+0.5); \path[draw,thick,->] (0,0-0.5) -- (8,-4+0.5); - \node at (-12,-8) {$\texttt{gen}(3)$}; - \node at (-4,-8) {$\texttt{gen}(3)$}; - \node at (4,-8) {$\texttt{gen}(3)$}; - \node at (12,-8) {$\texttt{gen}(3)$}; + \node at (-12,-8) {$\texttt{gen}(2)$}; + \node at (-4,-8) {$\texttt{gen}(2)$}; + \node at (4,-8) {$\texttt{gen}(2)$}; + \node at (12,-8) {$\texttt{gen}(2)$}; \path[draw,thick,->] (-8,-4-0.5) -- (-12,-8+0.5); \path[draw,thick,->] (-8,-4-0.5) -- (-4,-8+0.5); \path[draw,thick,->] (8,-4-0.5) -- (4,-8+0.5); \path[draw,thick,->] (8,-4-0.5) -- (12,-8+0.5); - \node at (-14,-12) {$\texttt{gen}(4)$}; - \node at (-10,-12) {$\texttt{gen}(4)$}; - \node at (-6,-12) {$\texttt{gen}(4)$}; - \node at (-2,-12) {$\texttt{gen}(4)$}; - \node at (2,-12) {$\texttt{gen}(4)$}; - \node at (6,-12) {$\texttt{gen}(4)$}; - \node at (10,-12) {$\texttt{gen}(4)$}; - \node at (14,-12) {$\texttt{gen}(4)$}; + \node at (-14,-12) {$\texttt{gen}(3)$}; + \node at (-10,-12) {$\texttt{gen}(3)$}; + \node at (-6,-12) {$\texttt{gen}(3)$}; + \node at (-2,-12) {$\texttt{gen}(3)$}; + \node at (2,-12) {$\texttt{gen}(3)$}; + \node at (6,-12) {$\texttt{gen}(3)$}; + \node at (10,-12) {$\texttt{gen}(3)$}; + \node at (14,-12) {$\texttt{gen}(3)$}; \node at (-14,-13.5) {$\emptyset$}; - \node at (-10,-13.5) {$\{3\}$}; - \node at (-6,-13.5) {$\{2\}$}; - \node at (-2,-13.5) {$\{2,3\}$}; - \node at (2,-13.5) {$\{1\}$}; - \node at (6,-13.5) {$\{1,3\}$}; - \node at (10,-13.5) {$\{1,2\}$}; - \node at (14,-13.5) {$\{1,2,3\}$}; + \node at (-10,-13.5) {$\{2\}$}; + \node at (-6,-13.5) {$\{1\}$}; + \node at (-2,-13.5) {$\{1,2\}$}; + \node at (2,-13.5) {$\{0\}$}; + \node at (6,-13.5) {$\{0,2\}$}; + \node at (10,-13.5) {$\{0,1\}$}; + \node at (14,-13.5) {$\{0,1,2\}$}; \path[draw,thick,->] (-12,-8-0.5) -- (-14,-12+0.5); @@ -135,14 +135,14 @@ The usual convention is that the $k$th element is included in the subset exactly when the $k$th last bit in the sequence is one. For example, the bit representation of 25 -is 11001, that corresponds to the subset $\{1,4,5\}$. +is 11001, that corresponds to the subset $\{0,3,4\}$. The following code goes through all subsets of a set of $n$ elements \begin{lstlisting} for (int b = 0; b < (1< v; + vector subset; for (int i = 0; i < n; i++) { - if (b&(1< v; -for (int i = 1; i <= n; i++) { - v.push_back(i); +vector perm; +for (int i = 0; i < n; i++) { + perm.push_back(i); } do { - // process permutation v -} while (next_permutation(v.begin(),v.end())); + // process permutation +} while (next_permutation(perm.begin(),perm.end())); \end{lstlisting} \section{Backtracking} @@ -344,7 +342,7 @@ The following code implements the search: \begin{lstlisting} void search(int y) { if (y == n) { - c++; + count++; return; } for (int x = 0; x < n; x++) { @@ -359,7 +357,7 @@ void search(int y) { The search begins by calling \texttt{search(0)}. The size of the board is $n$, and the code calculates the number of solutions -to $c$. +to \texttt{count}. The code assumes that the rows and columns of the board are numbered from 0. diff --git a/chapter07.tex b/chapter07.tex index 2ab4339..4f2d08f 100644 --- a/chapter07.tex +++ b/chapter07.tex @@ -122,7 +122,7 @@ Thus, the recursive formula is where the function $\min$ gives the smallest of its parameters. In the general case, for the coin set -$\{c_1,c_2,\ldots,c_k\}$, +$\{c_0,c_1,\ldots,c_{k-1}\}$, the recursive formula is \[f(x) = \min(f(x-c_1),f(x-c_2),\ldots,f(x-c_k))+1.\] The base case for the function is @@ -153,7 +153,7 @@ int f(int x) { \end{lstlisting} The code assumes that the available coins are -$\texttt{c}[1], \texttt{c}[2], \ldots, \texttt{c}[k]$, +stored in an array $\texttt{c}$, and the constant \texttt{INF} denotes infinity. This function works but it is not efficient yet, because it goes through a large number @@ -324,7 +324,7 @@ a sum $x$ using the coins. For example, $f(5)=6$ when the coins are $\{1,3,4\}$. The value of $f(x)$ can be calculated recursively using the formula -\[ f(x) = f(x-c_1)+f(x-c_2)+\cdots+f(x-c_k),\] +\[ f(x) = f(x-c_1)+f(x-c_2)+\cdots+f(x-c_{k}),\] because to form the sum $x$, we have to first choose some coin $c_i$ and then form the sum $x-c_i$. The base cases are $f(0)=1$, because there is exactly @@ -393,7 +393,7 @@ possibilities of dynamic programming. \index{longest increasing subsequence} Given an array that contains $n$ -numbers $x_1,x_2,\ldots,x_n$, +numbers, our task is to find the \key{longest increasing subsequence} of the array. @@ -416,14 +416,14 @@ For example, in the array \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$}; +\node at (0.5,1.4) {$0$}; +\node at (1.5,1.4) {$1$}; +\node at (2.5,1.4) {$2$}; +\node at (3.5,1.4) {$3$}; +\node at (4.5,1.4) {$4$}; +\node at (5.5,1.4) {$5$}; +\node at (6.5,1.4) {$6$}; +\node at (7.5,1.4) {$7$}; \end{tikzpicture} \end{center} the longest increasing subsequence @@ -449,14 +449,14 @@ contains 4 elements: \draw[thick,->] (4.6,-0.25) .. controls (5.0,-1.00) and (6.0,-1.00) .. (6.5,-0.25); \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$}; +\node at (0.5,1.4) {$0$}; +\node at (1.5,1.4) {$1$}; +\node at (2.5,1.4) {$2$}; +\node at (3.5,1.4) {$3$}; +\node at (4.5,1.4) {$4$}; +\node at (5.5,1.4) {$5$}; +\node at (6.5,1.4) {$6$}; +\node at (7.5,1.4) {$7$}; \end{tikzpicture} \end{center} @@ -465,19 +465,19 @@ longest increasing subsequence that ends at position $k$. Using this function, the answer to the problem is the largest of the values -$f(1),f(2),\ldots,f(n)$. +$f(0),f(1),\ldots,f(n-1)$. For example, in the above array the values of the function are as follows: \[ \begin{array}{lcl} +f(0) & = & 1 \\ f(1) & = & 1 \\ -f(2) & = & 1 \\ -f(3) & = & 2 \\ -f(4) & = & 1 \\ -f(5) & = & 3 \\ -f(6) & = & 2 \\ -f(7) & = & 4 \\ -f(8) & = & 2 \\ +f(2) & = & 2 \\ +f(3) & = & 1 \\ +f(4) & = & 3 \\ +f(5) & = & 2 \\ +f(6) & = & 4 \\ +f(7) & = & 2 \\ \end{array} \] @@ -486,11 +486,12 @@ there are two possibilities how the subsequence that ends at position $k$ is constructed: \begin{enumerate} \item The subsequence -only contains the element $x_k$. In this case $f(k)=1$. +only contains the element at position $k$. In this case $f(k)=1$. \item The subsequence is constructed -by adding the element $x_k$ to +by adding the element at position $k$ to a subsequence that ends at position $i$ -where $i] (0.5,-0.7) -- (0.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$}; +% +% \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{center} @@ -185,16 +185,16 @@ the sum would become too large. \draw[thick,->] (1.5,-0.7) -- (1.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$}; +% +% \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{center} @@ -220,16 +220,16 @@ where the sum of the elements is $x$. \draw[thick,->] (2.5,-0.7) -- (2.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$}; +% +% \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{center} @@ -283,16 +283,16 @@ with target sum $x=12$: \node at (5.5,0.5) {$9$}; \node at (6.5,0.5) {$9$}; \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$}; +% +% \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{center} @@ -318,16 +318,16 @@ that is smaller than $x$. \draw[thick,->] (0.5,-0.7) -- (0.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$}; +% +% \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{center} @@ -352,16 +352,16 @@ and the sum becomes $4+7=11$. \draw[thick,->] (1.5,-0.7) -- (1.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$}; +% +% \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{center} @@ -386,16 +386,16 @@ $5+7=12$ has been found. \draw[thick,->] (2.5,-0.7) -- (2.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$}; +% +% \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{center} @@ -477,16 +477,16 @@ As an example, consider the following array: \node at (5.5,0.5) {$3$}; \node at (6.5,0.5) {$4$}; \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$}; +% +% \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{center} @@ -510,16 +510,16 @@ and the nearest smaller element of 3 is 1. \draw[thick,->] (2.5,-0.25) .. controls (2.25,-1.00) and (1.75,-1.00) .. (1.6,-0.25); \draw[thick,->] (1.4,-0.25) .. controls (1.25,-1.00) and (0.75,-1.00) .. (0.5,-0.25); - -\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$}; +% +% \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{center} @@ -543,16 +543,16 @@ Its nearest smaller element is 1: \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); - -\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$}; +% +% \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{center} @@ -575,16 +575,16 @@ its nearest smaller element is 2: \draw[thick,->] (3.4,-0.25) .. controls (3.00,-1.00) and (1.00,-1.00) .. (0.5,-0.25); \draw[thick,->] (4.5,-0.25) .. controls (4.25,-1.00) and (3.75,-1.00) .. (3.6,-0.25); - -\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$}; +% +% \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{center} @@ -651,16 +651,16 @@ As an example, consider the following array: \node at (5.5,0.5) {$4$}; \node at (6.5,0.5) {$1$}; \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$}; +% +% \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{center} @@ -679,16 +679,16 @@ At the first window position, the smallest element is 1: \node at (5.5,0.5) {$4$}; \node at (6.5,0.5) {$1$}; \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$}; +% +% \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[thick,->] (2.4,-0.25) .. controls (2.25,-1.00) and (1.75,-1.00) .. (1.5,-0.25); @@ -715,16 +715,16 @@ The smallest element is still 1. \node at (5.5,0.5) {$4$}; \node at (6.5,0.5) {$1$}; \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$}; +% +% \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); @@ -750,16 +750,16 @@ is added to the chain. \node at (5.5,0.5) {$4$}; \node at (6.5,0.5) {$1$}; \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$}; +% +% \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); \end{tikzpicture} @@ -782,16 +782,16 @@ and it will only contain the element 1: \node at (5.5,0.5) {$4$}; \node at (6.5,0.5) {$1$}; \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$}; +% +% \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); @@ -816,16 +816,16 @@ is still 1. \node at (5.5,0.5) {$4$}; \node at (6.5,0.5) {$1$}; \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$}; +% +% \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); \end{tikzpicture} diff --git a/chapter09.tex b/chapter09.tex index 2bbaf74..9121590 100644 --- a/chapter09.tex +++ b/chapter09.tex @@ -16,7 +16,7 @@ Typical range queries are: \item \key{minimum query}: find the smallest element \item \key{maximum query}: find the largest element \end{itemize} -For example, consider the range $[4,7]$ in the following array: +For example, consider the range $[3,6]$ in the following array: \begin{center} \begin{tikzpicture}[scale=0.7] \fill[color=lightgray] (3,0) rectangle (7,1); @@ -32,14 +32,14 @@ For example, consider the range $[4,7]$ in the following array: \node at (7.5,0.5) {$4$}; \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$}; +\node at (0.5,1.4) {$0$}; +\node at (1.5,1.4) {$1$}; +\node at (2.5,1.4) {$2$}; +\node at (3.5,1.4) {$3$}; +\node at (4.5,1.4) {$4$}; +\node at (5.5,1.4) {$5$}; +\node at (6.5,1.4) {$6$}; +\node at (7.5,1.4) {$7$}; \end{tikzpicture} \end{center} In this range, the sum of elements is $4+6+1+3=16$, @@ -105,14 +105,14 @@ For example, consider the following array: \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$}; +\node at (0.5,1.4) {$0$}; +\node at (1.5,1.4) {$1$}; +\node at (2.5,1.4) {$2$}; +\node at (3.5,1.4) {$3$}; +\node at (4.5,1.4) {$4$}; +\node at (5.5,1.4) {$5$}; +\node at (6.5,1.4) {$6$}; +\node at (7.5,1.4) {$7$}; \end{tikzpicture} \end{center} The corresponding prefix sum array is as follows: @@ -132,27 +132,27 @@ The corresponding prefix sum array is as follows: \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$}; +\node at (0.5,1.4) {$0$}; +\node at (1.5,1.4) {$1$}; +\node at (2.5,1.4) {$2$}; +\node at (3.5,1.4) {$3$}; +\node at (4.5,1.4) {$4$}; +\node at (5.5,1.4) {$5$}; +\node at (6.5,1.4) {$6$}; +\node at (7.5,1.4) {$7$}; \end{tikzpicture} \end{center} Let $\textrm{sum}(a,b)$ denote the sum of elements in the range $[a,b]$. Since the prefix sum array contains all values -of the form $\textrm{sum}(1,k)$, +of the form $\textrm{sum}(0,k)$, we can calculate any value of $\textrm{sum}(a,b)$ in $O(1)$ time, because -\[ \textrm{sum}(a,b) = \textrm{sum}(1,b) - \textrm{sum}(1,a-1).\] -By defining $\textrm{sum}(1,0)=0$, +\[ \textrm{sum}(a,b) = \textrm{sum}(0,b) - \textrm{sum}(0,a-1).\] +By defining $\textrm{sum}(0,-1)=0$, the above formula also holds when $a=1$. -For example, consider the range $[4,7]$: +For example, consider the range $[3,6]$: \begin{center} \begin{tikzpicture}[scale=0.7] \fill[color=lightgray] (3,0) rectangle (7,1); @@ -168,14 +168,14 @@ For example, consider the range $[4,7]$: \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$}; +\node at (0.5,1.4) {$0$}; +\node at (1.5,1.4) {$1$}; +\node at (2.5,1.4) {$2$}; +\node at (3.5,1.4) {$3$}; +\node at (4.5,1.4) {$4$}; +\node at (5.5,1.4) {$5$}; +\node at (6.5,1.4) {$6$}; +\node at (7.5,1.4) {$7$}; \end{tikzpicture} \end{center} The sum in the range is $8+6+1+4=19$. @@ -198,17 +198,17 @@ two values in the prefix sum array: \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$}; +\node at (0.5,1.4) {$0$}; +\node at (1.5,1.4) {$1$}; +\node at (2.5,1.4) {$2$}; +\node at (3.5,1.4) {$3$}; +\node at (4.5,1.4) {$4$}; +\node at (5.5,1.4) {$5$}; +\node at (6.5,1.4) {$6$}; +\node at (7.5,1.4) {$7$}; \end{tikzpicture} \end{center} -Thus, the sum in the range $[4,7]$ is $27-8=19$. +Thus, the sum in the range $[3,6]$ is $27-8=19$. It is also possible to generalize this idea to higher dimensions. @@ -274,14 +274,14 @@ For example, for the array \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$}; +\node at (0.5,1.4) {$0$}; +\node at (1.5,1.4) {$1$}; +\node at (2.5,1.4) {$2$}; +\node at (3.5,1.4) {$3$}; +\node at (4.5,1.4) {$4$}; +\node at (5.5,1.4) {$5$}; +\node at (6.5,1.4) {$6$}; +\node at (7.5,1.4) {$7$}; \end{tikzpicture} \end{center} the following values will be calculated: @@ -292,14 +292,14 @@ the following values will be calculated: \begin{tabular}{ccc} $a$ & $b$ & $\textrm{rmq}(a,b)$ \\ \hline -1 & 1 & 1 \\ -2 & 2 & 3 \\ -3 & 3 & 4 \\ -4 & 4 & 8 \\ -5 & 5 & 6 \\ -6 & 6 & 1 \\ -7 & 7 & 4 \\ -8 & 8 & 2 \\ +0 & 0 & 1 \\ +1 & 1 & 3 \\ +2 & 2 & 4 \\ +3 & 3 & 8 \\ +4 & 4 & 6 \\ +5 & 5 & 1 \\ +6 & 6 & 4 \\ +7 & 7 & 2 \\ \end{tabular} & @@ -307,13 +307,13 @@ $a$ & $b$ & $\textrm{rmq}(a,b)$ \\ \begin{tabular}{ccc} $a$ & $b$ & $\textrm{rmq}(a,b)$ \\ \hline -1 & 2 & 1 \\ -2 & 3 & 3 \\ -3 & 4 & 4 \\ -4 & 5 & 6 \\ +0 & 1 & 1 \\ +1 & 2 & 3 \\ +2 & 3 & 4 \\ +3 & 4 & 6 \\ +4 & 5 & 1 \\ 5 & 6 & 1 \\ -6 & 7 & 1 \\ -7 & 8 & 2 \\ +6 & 7 & 2 \\ \\ \end{tabular} @@ -322,12 +322,12 @@ $a$ & $b$ & $\textrm{rmq}(a,b)$ \\ \begin{tabular}{ccc} $a$ & $b$ & $\textrm{rmq}(a,b)$ \\ \hline -1 & 4 & 1 \\ -2 & 5 & 3 \\ +0 & 3 & 1 \\ +1 & 4 & 3 \\ +2 & 5 & 1 \\ 3 & 6 & 1 \\ 4 & 7 & 1 \\ -5 & 8 & 1 \\ -1 & 8 & 1 \\ +0 & 7 & 1 \\ \\ \\ \end{tabular} @@ -352,7 +352,7 @@ We can calculate the value of $\textrm{rmq}(a,b)$ using the formula In the above formula, the range $[a,b]$ is represented as the union of the ranges $[a,a+k-1]$ and $[b-k+1,b]$, both of length $k$. -As an example, consider the range $[2,7]$: +As an example, consider the range $[1,6]$: \begin{center} \begin{tikzpicture}[scale=0.7] \fill[color=lightgray] (1,0) rectangle (7,1); @@ -368,21 +368,21 @@ As an example, consider the range $[2,7]$: \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$}; +\node at (0.5,1.4) {$0$}; +\node at (1.5,1.4) {$1$}; +\node at (2.5,1.4) {$2$}; +\node at (3.5,1.4) {$3$}; +\node at (4.5,1.4) {$4$}; +\node at (5.5,1.4) {$5$}; +\node at (6.5,1.4) {$6$}; +\node at (7.5,1.4) {$7$}; \end{tikzpicture} \end{center} The length of the range is 6, and the largest power of two that does not exceed 6 is 4. -Thus the range $[2,7]$ is -the union of the ranges $[2,5]$ and $[4,7]$: +Thus the range $[1,6]$ is +the union of the ranges $[1,4]$ and $[3,6]$: \begin{center} \begin{tikzpicture}[scale=0.7] \fill[color=lightgray] (1,0) rectangle (5,1); @@ -398,14 +398,14 @@ the union of the ranges $[2,5]$ and $[4,7]$: \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$}; +\node at (0.5,1.4) {$0$}; +\node at (1.5,1.4) {$1$}; +\node at (2.5,1.4) {$2$}; +\node at (3.5,1.4) {$3$}; +\node at (4.5,1.4) {$4$}; +\node at (5.5,1.4) {$5$}; +\node at (6.5,1.4) {$6$}; +\node at (7.5,1.4) {$7$}; \end{tikzpicture} \end{center} \begin{center} @@ -424,18 +424,18 @@ the union of the ranges $[2,5]$ and $[4,7]$: \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$}; +\node at (0.5,1.4) {$0$}; +\node at (1.5,1.4) {$1$}; +\node at (2.5,1.4) {$2$}; +\node at (3.5,1.4) {$3$}; +\node at (4.5,1.4) {$4$}; +\node at (5.5,1.4) {$5$}; +\node at (6.5,1.4) {$6$}; +\node at (7.5,1.4) {$7$}; \end{tikzpicture} \end{center} -Since $\textrm{rmq}(2,5)=3$ and $\textrm{rmq}(4,7)=1$, -we can conclude that $\textrm{rmq}(2,7)=1$. +Since $\textrm{rmq}(1,4)=2$ and $\textrm{rmq}(3,6)=0$, +we can conclude that $\textrm{rmq}(1,6)=1$. \section{Binary indexed trees} @@ -458,9 +458,12 @@ whole array again in $O(n)$ time. \subsubsection{Structure} +In this section we assume that one-based indexing +is used in all arrays. A binary indexed tree can be represented as an array where the value at position $x$ -equals the sum of elements in the range $[x-k+1,x]$, +equals the sum of elements in the range $[x-k+1,x]$ +of the original array, where $k$ is the largest power of two that divides $x$. For example, if $x=6$, then $k=2$, because 2 divides 6 but 4 does not divide 6. diff --git a/chapter18.tex b/chapter18.tex index ca06440..7106dec 100644 --- a/chapter18.tex +++ b/chapter18.tex @@ -168,17 +168,17 @@ Hence, the corresponding tree traversal array is as follows: \node at (6.5,0.5) {$8$}; \node at (7.5,0.5) {$9$}; \node at (8.5,0.5) {$5$}; - -\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$}; -\node at (8.5,1.4) {$9$}; +% +% \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$}; +% \node at (8.5,1.4) {$9$}; \end{tikzpicture} \end{center} @@ -203,17 +203,17 @@ nodes in the subtree of node $4$: \node at (6.5,0.5) {$8$}; \node at (7.5,0.5) {$9$}; \node at (8.5,0.5) {$5$}; - -\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$}; -\node at (8.5,1.4) {$9$}; +% +% \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$}; +% \node at (8.5,1.4) {$9$}; \end{tikzpicture} \end{center} Using this fact, we can efficiently process queries @@ -306,17 +306,17 @@ For example, the array for the above tree is as follows: \node at (6.5,-1.5) {$3$}; \node at (7.5,-1.5) {$1$}; \node at (8.5,-1.5) {$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$}; -\node at (8.5,1.4) {$9$}; +% +% \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$}; +% \node at (8.5,1.4) {$9$}; \end{tikzpicture} \end{center} @@ -366,17 +366,17 @@ can be found as follows: \node at (6.5,-1.5) {$3$}; \node at (7.5,-1.5) {$1$}; \node at (8.5,-1.5) {$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$}; -\node at (8.5,1.4) {$9$}; +% +% \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$}; +% \node at (8.5,1.4) {$9$}; \end{tikzpicture} \end{center} @@ -478,17 +478,17 @@ For example, the following array corresponds to the above tree: \node at (6.5,-1.5) {$12$}; \node at (7.5,-1.5) {$10$}; \node at (8.5,-1.5) {$6$}; - -\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$}; -\node at (8.5,1.4) {$9$}; +% +% \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$}; +% \node at (8.5,1.4) {$9$}; \end{tikzpicture} \end{center} @@ -535,17 +535,17 @@ the array changes as follows: \node at (6.5,-1.5) {$13$}; \node at (7.5,-1.5) {$11$}; \node at (8.5,-1.5) {$6$}; - -\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$}; -\node at (8.5,1.4) {$9$}; +% +% \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$}; +% \node at (8.5,1.4) {$9$}; \end{tikzpicture} \end{center}