0% found this document useful (0 votes)
25 views

Exercise Sheets

Uploaded by

eyuel.ap24
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
25 views

Exercise Sheets

Uploaded by

eyuel.ap24
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 49

Eidgenössische Ecole polytechnique fédérale de Zurich

Technische Hochschule Politecnico federale di Zurigo


Zürich Federal Institute of Technology at Zurich

Departement of Computer Science 26 September 2022


Markus Püschel, David Steurer
François Hublet, Goran Zuzic, Tommaso d’Orsi, Ding Jingqiu

Algorithms & Data Structures Exercise sheet 0 HS 22

The solutions for this sheet do not have to be submitted. The sheet will be solved in the first exercise
session on 26.09.2022.
Exercises that are marked by ∗ are challenge exercises.

Exercise 0.1 Induction.


a) Prove by mathematical induction that for any positive integer n,

n(n + 1)
1 + 2 + ··· + n = .
2

b) (This subtask is from August 2019 exam). Let T : N → R be a function that satisfies the
following two conditions:

T (n) ≥ 4 · T ( n2 ) + 3n whenever n is divisible by 2;


T (1) = 4.

Prove by mathematical induction that

T (n) ≥ 6n2 − 2n

holds whenever n is a power of 2, i.e., n = 2k with k ∈ N0 .

Asymptotic Growth
When we estimate the number of elementary operations executed by algorithms, it is often useful to
ignore smaller order terms, and instead focus on the asymptotic growth defined below. We denote by
R+ the set of all (strictly) positive real numbers and by R+
0 the set of nonnegative real numbers.

Definition 1. Let f, g : N → R+ be two functions. We say that f grows asymptotically faster than g if
lim fg(n)
(n) = 0.
n→∞
g(n)
This definition is also valid for functions defined on R+ instead of N. In general, lim is the same
n→∞ f (n)
g(x)
as lim if the second limit exists.
x→∞ f (x)

Exercise 0.2 Comparison of functions part 1.


Show that
a) f (n) := n log n grows asymptotically faster than g(n) := n.
b) f (n) := n3 grows asymptotically faster than g(n) := 10n2 + 100n + 1000.

c) f (n) := 3n grows asymptotically faster than g(n) := 2n .

The following theorem can be useful to compute some limits.


Theorem 1 (L’Hôpital’s rule). Assume that functions f : R+ → R+ and g : R+ → R+ are differentiable,
0 (x) 0 (x)
lim f (x) = lim g(x) = ∞ and for all x ∈ R+ , g 0 (x) 6= 0. If lim fg0 (x) = C ∈ R+
0 or lim fg0 (x) = ∞,
x→∞ x→∞ x→∞ x→∞
then
f (x) f 0 (x)
lim = lim 0 .
x→∞ g(x) x→∞ g (x)

Exercise 0.3 Comparison of functions part 2.


Show that
a) f (n) := n1.01 grows asymptotically faster than g(n) := n ln n.

b) f (n) := en grows asymptotically faster than g(n) := n.

c) f (n) := en grows asymptotically faster than g(n) := n2 .

d)∗ f (n) := 1.01n grows asymptotically faster than g(n) := n100 .

e)∗ f (n) := log2 n grows asymptotically faster than g(n) := log2 log2 n.


f)∗ f (n) := 2 log2 n grows asymptotically faster than g(n) := log100
2 n.


g)∗ f (n) := n0.01 grows asymptotically faster than g(n) := 2 log2 n .

Exercise 0.4 Simplifying expressions.


Simplify the following expressions as much as possible without changing their asymptotic growth rates.
Concretely, for each expression f (n) in the following list, find an expression g(n) that is as simple as
possible and that satisfies lim fg(n)
(n)
∈ R+ .
n→∞

It is guaranteed that all functions in this exercise take values in R+ (you don’t have to prove it).
a) f (n) := 5n3 + 40n2 + 100

1
b) f (n) := 5n + ln n + 2n3 + n

c) f (n) := n ln n − 2n + 3n2


d) f (n) := 23n + 4n log5 n6 + 78 n − 9

2
√ p
e) f (n) := log2 n5 + log2 n5

√ log log n √ log log n


f)∗ f (n) := 2n3 + 4
n 5 6 + 7n 8 9

Exercise 0.5∗ Finding the range of your bow.


To celebrate your start at ETH, your parents gifted you a bow and (an infinite number of) arrows. You
would like to determine the range of your bow, in other words how far you can shoot arrows with it.
For simplicity we assume that all your arrow shots will cover exactly the same distance r, and we define
r as the range of your bow. You also know that this range is at least r ≥ 1 (meter).
You have at your disposition a ruler and a wall. You cannot directly measure the distance covered by
an arrow shot (because the arrow slides some more distance on the ground after reaching distance r),
so the only way you can get information about the range r is as follows. You can stand at a distance `
(of your choice) from the wall and shoot an arrow: if the arrow reaches the wall, you know that ` ≤ r,
and otherwise you deduce that ` > r. By performing such an experiment with various choices of the
distance `, you will be able to determine r with more and more accuracy. Your goal is to do so with as
few arrow shots as possible.
a) What is a fast strategy to find an upper bound on the range r ? In other words, how can you
find a distance D ≥ 1 such that r < D, using few arrow shots ? The required number of shots
might depend on the actual range r, so we will denote it by f (r). Good solutions should have
f (r) ≤ 10 log2 r for large values of r.
b) You are now interested in determining r up to some additive error. More precisely, you should find
an estimate r̃ such that the range is contained in the interval [r̃ − 1, r̃ + 1], i.e. r̃ − 1 ≤ r ≤ r̃ + 1.
Denoting by g(r) the number of shots required by your strategy, your goal is to find a strategy with
g(r) ≤ 10 log2 r for all r sufficiently large.
c) Coming back to part (a), is it possible to have a significantly faster strategy (for example with f (r) ≤
10 log2 log2 r for large values of r) ?

3
Eidgenössische Ecole polytechnique fédérale de Zurich
Technische Hochschule Politecnico federale di Zurigo
Zürich Federal Institute of Technology at Zurich

Departement of Computer Science 26 September 2022


Markus Püschel, David Steurer
François Hublet, Goran Zuzic, Tommaso d’Orsi, Jingqiu Ding

Algorithms & Data Structures Exercise sheet 1 HS 22

The solutions for this sheet are submitted at the beginning of the exercise class on 3 October 2022.
Exercises that are marked by ∗ are “challenge exercises”. They do not count towards bonus points.
You can use results from previous parts without solving those parts.

Exercise 1.1 Guess the formula (1 point).


Consider the recursive formula defined by a1 = 1 and an+1 = 2an + 1. Find a simple closed formula
for an and prove that an follows it using induction.

Hint: Write out the first few terms. How fast does the sequence grow?

Exercise 1.2 Sum of Squares.


Prove by mathematical induction that for every positive integer n,

n(n + 1)(2n + 1)
12 + 22 + · · · + n2 = .
6

Exercise 1.3 Sums of powers of integers (1 point).


In this exercise, we fix an integer k ∈ N0 .
(a) Show that, for all n ∈ N0 , we have ni=1 ik ≤ nk+1 .
P

(b) Show that for all n ∈ N0 , we have ni=1 ik ≥ 2k+11


· nk+1 .
P

Hint: Consider the second half of the sum, i.e., ni=d n e ik . How many terms are there in this sum?
P
2
How small can they be?
Together, these two inequalities show that C1 · nk+1 ≤ ni=1 ik ≤ C2 · nk+1 , where C1 = 2k+1 1
and
P
Pn k
C2 = 1 are two constants independent of n. Hence, when n is large, i=1 i behaves “almost like
nk+1 ” up to a constant factor.

Exercise 1.4 Asymptotic growth (1 point).


Recall the concept of asymptotic growth that we introduced in Exercise sheet 0: If f, g : N → R+ are
two functions, then:
• We say that f grows asymptotically slower than g if lim fg(m)
(m)
= 0. If this is the case, we also
m→∞
say that g grows asymptotically faster than f .
Prove or disprove each of the following statements.
(a) f (m) = 100m3 + 10m2 + m grows asymptotically slower than g(m) = 0.001 · m5 .
(b) f (m) = log (m3 ) grows asymptotically slower than g(m) = (log m)3 .
(c) f (m) = e2m grows asymptotically slower than g(m) = 23m .
Hint: Recall that for all n, m ∈ N, we have nm = em ln n .
P 2
(d) f (m) = m
Pm 2
i=1 i grows asymptotically slower than g(m) = i=1 i .

Hint: You can reuse the inequalities from exercise 1.2.


(e)* If f (m) grows asymptotically slower than g(m), then log(f (m)) grows asymptotically slower than
log(g(m)).

(f)* f (m) = log( log(m)) grows asymptotically slower than g(m) = log( m).
p p

Hint: You can use L’Hôpital’s rule from sheet 0.

Exercise 1.5 Proving Inequalities.


(a) By induction, prove the inequality
1 3 5 2n − 1 1
· · · ... · ≤√ , n ≥ 1.
2 4 6 2n 3n + 1

(b)* Replace 3n + 1 by 3n on the right side, and try to prove the new inequality by induction. This
inequality is even weaker, hence it must be true. However, the induction proof fails. Try to explain
to yourself how is this possible?

2
Eidgenössische Ecole polytechnique fédérale de Zurich
Technische Hochschule Politecnico federale di Zurigo
Zürich Federal Institute of Technology at Zurich

Departement of Computer Science 3 October 2022


Markus Püschel, David Steurer
François Hublet, Goran Zuzic, Tommaso d’Orsi, Jingqiu Ding

Algorithms & Data Structures Exercise sheet 2 HS 22

The solutions for this sheet are submitted at the beginning of the exercise class on 10 October 2022.
Exercises that are marked by ∗ are “challenge exercises”. They do not count towards bonus points.
You can use results from previous parts without solving those parts.

Exercise 2.1 Induction.


(a) Prove via mathematical induction that for all integers n ≥ 5,

2n > n2 .

(b) Let x be a real number. Prove via mathematical induction that for every positive integer n, we have
n  
X n i
(1 + x)n = x ,
i
i=0

where  
n n!
= .
i i!(n − i)!
We use a standard convention 0! = 1, so n0 = nn = 1 for every positive integer n.
 

Hint: Y ou can use the following fact without justification: for every 1 ≤ i ≤ n,
     
n n n+1
+ = .
i i−1 i

Exercise 2.2 Growth of Fibonacci numbers (1 point).


There are a lot of neat properties of the Fibonacci numbers that can be proved by induction. Recall that
the Fibonacci numbers are defined by f0 = 0, f1 = 1 and the recursion relation fn+1 = fn + fn−1 for
all n ≥ 1. For example, f2 = 1, f5 = 5, f10 = 55, f15 = 610.
(a) Prove that fn+1 ≤ 1.75n for n ≥ 0.
(b) Prove that fn ≥ 1
3 · 1.5n for n ≥ 1.

Asymptotic Notation
When we estimate the number of elementary operations executed by algorithms, it is often useful
to ignore constant factors and instead use the following kind of asymptotic notation, also called O-
Notation. We denote by R+ the set of all (strictly) positive real numbers and by N the set of all (strictly)
positive integers.

Definition 1 (O-Notation). Let n0 ∈ N, N := {n0 , n0 + 1, . . .} and let f : N → R+ . O(f ) is the set


of all functions g : N → R+ such that there exists C > 0 such that for all n ∈ N , g(n) ≤ Cf (n).
In general, we say that g ≤ O(f ) if Definition 1 applies after restricting the domain to some N =
{n0 , n0 + 1, . . .}. Some sources use the notation g = O(f ) or g ∈ O(f ) instead.
Instead of working with this definition directly, it is often easier to use limits in the way provided by
the following theorem.

Theorem 1 (Theorem 1.1 from the script). Let f : N → R+ and g : N → R+ .


f (n)
• If lim = 0, then f ≤ O(g) and g 6≤ O(f ).
n→∞ g(n)
f (n)
• If lim = C ∈ R+ , then f ≤ O(g) and g ≤ O(f ).
n→∞ g(n)
f (n)
• If lim = ∞, then f 6≤ O(g) and g ≤ O(f ).
n→∞ g(n)
f (n)
The theorem holds all the same if the functions are defined on R+ instead of N . In general, lim
n→∞ g(n)
f (x)
is the same as lim if the second limit exists.
x→∞ g(x)

The following theorem can also be helpful when working with O-notation.
Theorem 2. Let f, g, h : N → R+ . If f ≤ O(h) and g ≤ O(h), then
1. For every constant c ≥ 0, c · f ≤ O(h).
2. f + g ≤ O(h).

Notice that for all real numbers a, b > 1, loga n = loga b · logb n (where loga b is a positive constant).
Hence loga n ≤ O(logb n). So you don’t have to write bases of logarithms in asymptotic notation, that
is, you can just write O(log n).

Exercise 2.3 O-notation quiz.


(a) Prove or disprove the following statements. Justify your answer.
2n+3
(1) n n+1 = O(n2 )
(2) e1.2n = O(en )
(3) log(n4 + n3 + n2 ) = O(log(n3 + n2 + n))

(b) Find f and g as in Theorem 1 such that f = O(g), but the limit limn→∞ fg(n)
(n)
does not exist. This
proves that the first point of Theorem 1 provides a necessary, but not a sufficient condition for
f = O(g).

2
Exercise 2.4 Asymptotic growth of ln(n!).
Recall that the factorial of a positive integer n is defined as n! = 1 × 2 × · · · × (n − 1) × n.
a) Show that ln(n!) ≤ O(n ln n).
Hint: You can use the fact that n! ≤ nn for n ≥ 1 without proof.
b) Show that n ln n ≤ O(ln(n!)).
n
n
Hint: You can use the fact that 2
2
≤ n! for n ≥ 1 without proof.

Exercise 2.5 Triplet Search (2 points).


Given an array of n integers, and an integer t, design an algorithm that checks if there exists three (not
necessarily different) elements of the array a, b, c such that a + b + c = t.
(a) Design a simple O(n3 ) algorithm.
(b) Suppose that elements of the array are integers in the range [1, 100n], and that t ≤ 300n. Design
a better algorithm with runtime O(n2 ) to solve the same problem, assuming the constraints.
Hint: You can use a separate array with O(n) entries to help you. Start with the “naive” algorithm
from (a) and try removing one of the loops with a smart lookup using the new array.
Hint: a + b + c = t implies that a = t − b − c.
(c)* Suppose now that, unlike in (b), we don’t have a bound on the size of the integers elements of A
nor on t (but we can still perform arithmetic operations on them in O(1) time). However, they are
given in increasing order in A, i.e., A[1] ≤ A[2] ≤ . . . A[n]. Design an O(n2 ) algorithm to solve
the same problem, assuming the constraints.
Hint: Exploit the increasing order of A to leverage the computation done in the previous step to help
you in the next one.

3
Eidgenössische Ecole polytechnique fédérale de Zurich
Technische Hochschule Politecnico federale di Zurigo
Zürich Federal Institute of Technology at Zurich

Departement of Computer Science 10 October 2022


Markus Püschel, David Steurer
François Hublet, Goran Zuzic, Tommaso d’Orsi, Jingqiu Ding

Algorithms & Data Structures Exercise sheet 3 HS 22

The solutions for this sheet are submitted at the beginning of the exercise class on 17 October 2022.
Exercises/questions marked by ∗ are “challenge exercises”. They do not count towards bonus points.
You can use results from previous parts without solving those parts.

Exercise 3.1 Some properties of O-Notation.


Let f : R+ → R+ and g : R+ → R+ .
(a) Show that if f ≤ O(g), then f 2 ≤ O(g 2 ).
(b) Does f ≤ O(g) imply 2f 6≤ O(2g )? Prove it or provide a counterexample.

Exercise 3.2 Substring counting (1 point).


Given a n-bit bitstring S (an array over {0, 1} of size n), and an integer k ≥ 0, we would like to count
the number of nonempty substrings of S with exactly k ones. For example, when S = “0110” and
k = 2, there are 4 such substrings: “011”, “11”, “110”, and “0110”.
(a) Design a “naive” algorithm that solves this problem with a runtime of O(n3 ). Justify its runtime
and correctness.
(b) We say that a bitstring S 0 is a (non-empty) prefix of a bitstring S if S 0 is of the form S[0..i] where
0 ≤ i < length(S). For example, the prefixes of S = “0110” are “0”, “01”, “011” and “0110”.
Given a n-bit bitstring S, we would like to compute a table T indexed by 0..n such that for all i,
T [i] contains the number of prefixes of S with exactly i ones.
For example, for S = “0110”, the desired table is T = [1, 1, 2, 0, 0], since, of the 4 prefixes of S, 1
prefix contains zero “1”, 1 prefix contains one “1”, 2 prefixes contain two “1”, and 0 prefix contains
three “1” or four “1”.
Describe an algorithm prefixtable that computes T from S in time O(n), assuming S has size n.
Remark: This algorithm can also be applied on a reversed bitstring to compute the same table for
all suffixes of S. In the following, you can assume an algorithm suffixtable that does exactly this.
(c) Let S be a n-bit bitstring. Consider an integer m ∈ {0, . . . , n − 1}, and divide bitstring S into two
substrings S[0..m] and S[m+1..n−1]. Using prefixtable and suffixtable, describe an algorithm
spanning(m, k, S) that returns the number of substrings S[i..j] of S that have exactly k ones and
such that i ≤ m < j. What is its complexity?
For example, if S = “0110”, k = 2, and m = 0, there exist exactly two such strings: “011” and
“0110”. Hence, spanning(m, k, S) = 2.
Hint: Each substring S[i..j] with i ≤ m < j can be obtained by concatenating a string S[i..m] that
is a suffix of S[0..m] and a string S[m + 1..j] that is a prefix of S[m + 1..n − 1].
*(d) Using spanning, design an algorithm with a runtime of at most O(n log n) that counts the number
of nonempty substrings of a n-bit bitstring S with exactly k ones. (You can assume that n is a power
of two.)
Hint: Use the recursive idea from the lecture.

Exercise 3.3 Counting function calls in loops (1 point).


For each of the following code snippets, compute the number of calls to f as a function of n. Provide
both the exact number of calls and a maximally simplified, tight asymptotic bound in big-O notation.

Algorithm 1
(a) f ()
i←0
while i ≤ n do
f ()
i←i+1

Algorithm 2
(b) i←0
while i2 ≤ n do
f ()
f ()
for j ← 1, . . . , n do
f ()
i←i+1

Exercise 3.4 Fibonacci Revisited (1 point).


In this exercise we continue playing with the Fibonacci sequence.
(a) Write an O(n) algorithm that computes the nth Fibonacci number. As a reminder, Fibonacci num-
bers are a sequence defined as f0 = 0, f1 = 1, and fn+2 = fn+1 + fn for all integers n ≥ 0.
Remark: As shown in the last week’s exercise sheet, fn grows exponentially (e.g., at least as fast as
Ω(1.5n )). On a physical computer, working with these numbers often causes overflow issues as they
exceed variables’ value limits. However, for this exercise, you can freely ignore any such issue and
assume we can safely do arithmetic on these numbers.
(b) Given an integer k ≥ 2, design an algorithm that computes the largest Fibonacci number fn such
that fn ≤ k. The algorithm should have complexity O(log k). Prove this.
Remark: Typically we express runtime in terms of the size of the input n. In this exercise, the runtime
will be expressed in terms of the input value k.
Hint: Use the bound proved in 2.2.(b).

2
*(c) Given an integer k ≥ 2, consider the following algorithm:

Algorithm 3
while k > 0 do
find the largest n such that fn ≤ k
k ← k − fn

Prove that the loop body is executed at most O(log k) times.


1
Hint: First, prove that fn−1 ≥ 2 · fn for all n.

Exercise 3.5 Iterative squaring.


In this exercise you are going to develop an algorithm to compute powers an , with a ∈ Z and n ∈
N, efficiently. For this exercise, we will treat multiplication of two integers as a single elementary
operation, i.e., for a, b ∈ Z you can compute a · b using one operation.
(a) Assume that n is even, and that you already know an algorithm An/2 (a) that efficiently computes
an/2 , i.e., An/2 (a) = an/2 . Given the algorithm An/2 , design an efficient algorithm An (a) that
computes an .
(b) Let n = 2k , for k ∈ N0 . Find an algorithm that computes an efficiently. Describe your algorithm
using pseudo-code.
(c) Determine the number of elementary operations (i.e., integer multiplications) required by your
algorithm for part b) in O-notation. You may assume that bookkeeping operations don’t cost any-
thing. This includes handling of counters, computing n/2 from n, etc.
(d) Let Power(a, n) denote your algorithm for the computation of an from part b). Prove the correctness
of your algorithm via mathematical induction for all n ∈ N that are powers of two.
In other words: show that Power(a, n) = an for all n ∈ N of the form n = 2k for some k ∈ N0 .
*(e) Design an algorithm that can compute an for a general n ∈ N, i.e., n does not need to be a power
of two.
Hint: Generalize the idea from part a) to the case where n is odd, i.e., there exists k ∈ N such that
n = 2k + 1.

3
Eidgenössische Ecole polytechnique fédérale de Zurich
Technische Hochschule Politecnico federale di Zurigo
Zürich Federal Institute of Technology at Zurich

Departement of Computer Science 17 October 2022


Markus Püschel, David Steurer
François Hublet, Goran Zuzic, Tommaso d’Orsi, Jingqiu Ding

Algorithms & Data Structures Exercise sheet 4 HS 22

The solutions for this sheet are submitted at the beginning of the exercise class on 24 October 2022.
Exercises that are marked by ∗ are “challenge exercises”. They do not count towards bonus points.
You can use results from previous parts without solving those parts.

Master Theorem. The following theorem is very useful for running-time analysis of divide-and-
conquer algorithms.

Theorem 1 (Master theorem). Let a, C > 0 and b ≥ 0 be constants and T : N → R+ a function such
that for all even n ∈ N,
T (n) ≤ aT (n/2) + Cnb . (1)
Then for all n = 2k , k ∈ N,
• If b > log2 a, T (n) ≤ O(nb ).
• If b = log2 a, T (n) ≤ O(nlog2 a · log n).
• If b < log2 a, T (n) ≤ O(nlog2 a ).
If the function T is increasing, then the condition n = 2k can be dropped. If (1) holds with “=”, then we
may replace O with Θ in the conclusion.

This generalizes some results that you have already seen in this course. For example, the (worst-case)
running time of Karatsuba algorithm satisfies T (n) ≤ 3T (n/2) + 100n, so a = 3 and b = 1 <
log2 3, hence T (n) ≤ O(nlog2 3 ). Another example is binary search: its running time satisfies T (n) ≤
T (n/2) + 100, so a = 1 and b = 0 = log2 1, hence T (n) ≤ O(log n).

Exercise 4.1 Applying Master theorem.


For this exercise, assume that n is a power of two (that is, n = 2k , where k ∈ {0, 1, 2, 3, 4, . . .}).
a) Let T (1) = 1, T (n) = 4T (n/2)+100n for n > 1. Using Master theorem, show that T (n) ≤ O(n2 ).
b) Let T (1) = 5, T (n) = T (n/2) + 32 n for n > 1. Using Master theorem, show that T (n) ≤ O(n).
c) Let T (1) = 4, T (n) = 4T (n/2) + 27 n2 for n > 1. Using Master theorem, show that T (n) ≤
O(n2 log n).
The following definitions are closely related to O-Notation and are also useful in running time analysis
of algorithms.
Definition 1 (Ω-Notation). Let n0 ∈ N, N := {n0 , n0 + 1, . . .} and let f : N → R+ . Ω(f ) is the set
of all functions g : N → R+ such that f ∈ O(g). One often writes g ≥ Ω(f ) instead of g ∈ Ω(f ).
Definition 2 (Θ-Notation). Let n0 ∈ N, N := {n0 , n0 + 1, . . .} and let f : N → R+ . Θ(f ) is the set
of all functions g : N → R+ such that f ∈ O(g) and g ∈ O(f ). One often writes g = Θ(f ) instead of
g ∈ Θ(f ).

Exercise 4.2 Asymptotic notations.


a) Give the (worst-case) running time of the following algorithms in Θ-Notation.
1) Karatsuba algorithm.
2) Binary Search.
3) Bubble Sort.
b) (This subtask is from January 2019 exam). For each of the following claims, state whether it is
true or false. You don’t need to justify your answers.

claim true false

n √
log n ≤ O( n)  

log(n!) ≥ Ω(n2 )  

nk ≥ Ω(k n ), if 1 < k ≤ O(1)  

log3 n4 = Θ(log7 n8 )  

c) (This subtask is from August 2019 exam). For each of the following claims, state whether it is
true or false. You don’t need to justify your answers.

claim true false

n
log n ≥ Ω(n1/2 )  

log7 (n8 ) = Θ(log3 (n n ))  

3n4 + n2 + n ≥ Ω(n2 )  

(∗) n! ≤ O(nn/2 )  

Note that the last claim is challenge. It was one of the hardest tasks of the exam. If you want a 6
grade, you should be able to solve such exercises.

Sorting and Searching.

Exercise 4.3 One-Looped Sort (1 point).

2
Consider the following pseudocode whose goal is to sort an array A containing n integers.

Algorithm 1 Input: array A[0 . . . n − 1].


i←0
while i < n do
if i = 0 or A[i] ≥ A[i − 1] then:
i←i+1
else
swap A[i] and A[i − 1]
i←i−1

(a) Show the steps of the algorithm on the input A = [10, 20, 30, 40, 50, 25] until termination. Specif-
ically, give the contents of the array A and the value of i after each iteration of the while loop.
(b) Explain why the algorithm correctly sorts any input array. Formulate a reasonable loop invariant,
prove it (e.g., using induction), and then conclude using invariant that the algorithm correctly sorts
the array.
Hint: Use the invariant “at the moment when the variable i gets incremented to a new value i = k for
the first time, the first k elements of the array are sorted in increasing order”.
(c) Give a reasonable running-time upper bound, expressed in O-notation.

Exercise 4.4 Searching for the summit (1 point).


Suppose we are given an array A[1 . . . n] with n unique integers that satisfies the following property.
There exists an integer k ∈ [1, n], called the summit index, such that A[1 . . . k] is a strictly increasing
array and A[k . . . n] is a strictly decreasing array. We say an array is valid is if satisfies the above
properties.
(a) Provide an algorithm that find this k with worst-case running time O(log n). Give the pseudocode
and give an argument why its worst-case running time is O(log n).
Note: Be careful about edge-cases! It could happen that k = 1 or k = n, and you don’t want to peek
outside of array bounds without taking due care.
(b) Given an integer x, provide an algorithm with running time O(log n) that checks if x appears in the
array of not. Describe the algorithm either in words or pseudocode and argue about its worst-case
running time.

Exercise 4.5 Counting function calls in loops (cont’d) (1 point).


For each of the following code snippets, compute the number of calls to f as a function of n. Provide
both the exact number of calls and a maximally simplified, tight asymptotic bound in big-O notation.

3
Algorithm 2
(a) i←0
while 2i < n do
j←i
while j < n do
f ()
j ←j+1
i←i+1

Algorithm 3
(b) i ← n
while i > 0 do
j←0
f ()
while j < n do
f ()
k←j
while k < n do
f ()
k ←k+1
j ←j+1
i ← b 2i c

4
Eidgenössische Ecole polytechnique fédérale de Zurich
Technische Hochschule Politecnico federale di Zurigo
Zürich Federal Institute of Technology at Zurich

Departement of Computer Science 24 October 2022


Markus Püschel, David Steurer
François Hublet, Goran Zuzic, Tommaso d’Orsi, Jingqiu Ding

Algorithms & Data Structures Exercise sheet 5 HS 22

The solutions for this sheet are submitted at the beginning of the exercise class on 31 October 2022.
Exercises that are marked by ∗ are “challenge exercises”. They do not count towards bonus points.
You can use results from previous parts without solving those parts.

Exercise 5.1 Heapsort (1 point).


Given the array [0, 7, 2, 8, 4, 6, 3, 1], we want to sort it in ascending order using Heapsort.
(a) Draw the tree interpretation of the array as a heap, before any call of RestoreHeapCondition.
(b) In the lecture you have learned a method to construct a heap from an unsorted array (see also pages
35–36 in the script). Draw the resulting max heap if this method is applied to the above array.
(c) Sort the above array in ascending order with heapsort, beginning with the heap that you obtained
in (b). Draw the array after each intermediate step in which a key is moved to its final position.

Exercise 5.2 Sorting algorithms.


Below you see four sequences of snapshots, each obtained in consecutive steps of the execution of
one of the following algorithms: InsertionSort, SelectionSort, QuickSort, MergeSort, and
BubbleSort. For each sequence, write down the corresponding algorithm.

3 6 5 1 2 4 8 7 3 6 5 1 2 4 8 7
3 6 5 1 2 4 8 7 3 5 1 2 4 6 7 8
3 5 6 1 2 4 8 7 3 1 2 4 5 6 7 8

3 6 5 1 2 4 8 7 3 6 5 1 2 4 8 7
3 6 1 5 2 4 7 8 1 6 5 3 2 4 8 7
1 3 5 6 2 4 7 8 1 2 5 3 6 4 8 7

Exercise 5.3 Counting function calls in recursive functions (1 point).


For each of the following functions g, h, and k, provide an asymptotic bound in big-O notation on the
number of calls to f as a function of n. You can assume that n is a power of two.
Algorithm 1
(a) function g(n)
i←1
while i < n do
f ()
i←i+2
g(n/2)
g(n/2)
g(n/2)

Algorithm 2
(b) function h(n)
i←1
while i < n do
f ()
i←i+1
k(n)
k(n)
function k(n)
i←2
while i < n do
f ()
i ← i2
h(n/2)

Exercise 5.4 Bubble sort invariant.


Consider the pseudocode of the bubble sort algorithm on an integer array A[1, . . . , n]:

Algorithm 3 BubbleSort(A)
for 1 ≤ i ≤ n do
for 1 ≤ j ≤ n − i do
if A[j] > A[j + 1] then
t ← A[j]
A[j] ← A[j + 1]
A[j + 1] ← t
return A

(a) Formulate an invariant INV(i) that holds at the end of the i-th iteration of the outer for-loop.
(b) Using the invariant from part (a), prove the correctness of the algorithm. Specifically, prove the
following three assertions:
(1) INV(1) holds.
(2) If INV(i) holds, then INV(i + 1) holds (for all 1 ≤ i < n).
(3) INV(n) implies that BubbleSort(A) correctly sorts the array A.

2
Exercise 5.5 Guessing a pair of numbers (1 point).
Alice and Bob play the following game:
• Alice selects two integers 1 ≤ a, b ≤ 1000, which she keeps secret
• Then, Alice and Bob repeat the following:
– Bob chooses two integers (a0 , b0 )
– If a = a0 and b = b0 , Bob wins
– If a > a0 and b > b0 , Alice tells Bob ‘high!’
– If a < a0 and b < b0 , Alice tells Bob ‘low!’
– Otherwise, Alice does not give any clue to Bob
Bob claims that he has a strategy to win this game in 12 attempts at most.
Prove that such a strategy cannot exist.
Hint: Represent Bob’s strategy as a decision tree. Each edge of the decision tree corresponds to one of Alice’s
answers, while each leaf corresponds to a win for Bob.
Hint: After defining the decision tree, you can consider the sequence k0 = 1, kn+1 = 3kn + 1, and prove
n+1
that kn = 3 2 −1 . The number of leaves in the decision tree of level n should be related kn .

3
Eidgenössische Ecole polytechnique fédérale de Zurich
Technische Hochschule Politecnico federale di Zurigo
Zürich Federal Institute of Technology at Zurich

Departement of Computer Science 31 October 2022


Markus Püschel, David Steurer
François Hublet, Goran Zuzic, Tommaso d’Orsi, Jingqiu Ding

Algorithms & Data Structures Exercise sheet 6 HS 22

The solutions for this sheet are submitted at the beginning of the exercise class on 07 November 2022.
Exercises that are marked by ∗ are “challenge exercises”. They do not count towards bonus points.
You can use results from previous parts without solving those parts.

Exercise 6.1 Longest ascending subsequence.


The longest ascending subsequence problem is concerned with finding a longest subsequence of a given
array A of length n such that the subsequence is sorted in ascending order. The subsequence does not
have to be contiguous and it may not be unique. For example if A = [1, 5, 4, 2, 8], a longest ascending
subsequence is 1, 5, 8. Other solutions are 1, 4, 8, and 1, 2, 8.
Given is the array:

[19, 3, 7, 1, 4, 15, 18, 16, 14, 6, 5, 10, 12, 19, 13, 17, 20, 8, 14, 11]

Use the dynamic programming algorithm from section 3.2. of the script to find the length of a longest
ascending subsequence and the subsequence itself. Provide the intermediate steps, i.e., DP-table up-
dates, of your computation.

Exercise 6.2 Coin Conversion (1 point).


Suppose you live in a country where the transactions between people are carried out by exchanging
coins denominated in dollars. The country uses coins with k different values, where the smallest coin
has value of b1 = 1 dollar, while other coins have values of b2 , b3 , . . . , bk dollars. You received a bill
for n dollars and want to pay it exactly using the smallest number of coins. Assuming you have an
unlimited supply of each type of coin, define OPT to be the minimum number of coins you need to
pay exactly n dollars. Your task is to calculate OPT. All values n, k, b1 , . . . , bk are positive integers.
Example: n = 17, k = 3 and b = [1, 9, 6], then OPT = 4 because 17 can be obtained via 4 coins as
1 + 1 + 9 + 6. No way to obtain 17 with three or less coins exists. (A previous version had a typo
“k = 4” that was corrected to “k = 3”.)
(a) Consider the pseudocode of the following algorithm that “tries” to compute OPT.
Algorithm 1
1: Input: integers n, k and an array b = [1 = b1 , b2 , b3 , . . . , bk ].
2:
3: counter ← 0
4: while n > 0 do
5: Let b[i] be the value of the largest coin b[i] such that b[i] ≤ n.
6: n ← n − b[i].
7: counter ← counter + 1
8: Print(“min. number of required coins = “, counter)

Algorithm 1 does not always produce the correct output. Show an example where the above algo-
rithms fails, i.e., when the output does not match OPT. Specify what are the values of n, k, b, what
is OPT and what does Algorithm 1 report.
(b) Consider the pseudocode below. Provide an upper bound in O notation that bounds the time it
takes a compute f [n] (it should be given in terms of n and k). Give a short high-level explanation
of your answer. For full points your upper bound should be tight (but you do not have to prove its
tightness).

Algorithm 2
1: Input: integers n, k. Array b = [1 = b1 , b2 , b3 , . . . , bk ].
2:
3: Let f [1 . . . n] be an array of integers.
4: f [0] ← 0 ▷ Terminating condition.
5: for N ← 1 . . . n do
6: f [N ] ← ∞ ▷ At first, we need ∞ coins. We try to improve upon that.
7: for i ← 1 . . . k do
8: if b[i] ≤ N then
9: val ← 1 + f [N − b[i]] ▷ Use coin b[i], it remains to optimally pay N − b[i].
10: f [N ] ← min(f [N ], val)
11: Print(f [n])

(c) Let OPT(N ) be the answer (min. number of coins needed) when n = N . Algorithm 2 (correctly)
computes a function f [N ] that is equal to OPT(N ). Formally prove why this is the case, i.e., why
f [N ] = OP T (N ).
Hint: Use induction to prove the invariant f [n] = OP T (n). Assume the claim holds for all values of
n ∈ {1, 2, . . . , N − 1}. Then show the same holds for n = N .
(d) Rewrite Algorithm 2 to be recursive and use memoization. The running time and correctness should
not be affected.

Exercise 6.3 Longest common subsequence.


Given are two arrays, A of length n, and B of length m, we want to find the their longest common
subsequence and its length. The subsequence does not have to be contiguous. For example, if A =
[1, 8, 5, 2, 3, 4] and B = [8, 2, 5, 1, 9, 3], a longest common subsequence is 8, 5, 3 and its length is 3.
Notice that 8, 2, 3 is another longest common subsequence.

2
Given are the two arrays:
A = [7, 6, 3, 2, 8, 4, 5, 1]
and
B = [3, 9, 10, 8, 7, 1, 2, 6, 4, 5],
Use the dynamic programming algorithm from Section 3.3 of the script to find the length of a longest
common subsequence and the subsequence itself. Show all necessary tables and information you used
to obtain the solution.

Exercise 6.4 Coin Collection (2 points).


Suppose you are playing a video game where your character’s goal is to collect as many coins in a
two-dimensional m × n grid world (m rows by n columns). The world is given to you as a table
A[1 . . . m][1 . . . n] where each cell is either a coin (denoted as “C”), impassible (denoted as “#”), or
passable without coins (denoted as “.”).
Your character starts at (1, 1) (this cell will always be passable) and, in each turn, can move either
right or down (up to your choice), or stop whenever (ending the game). Moving right corresponds to
moving from (x, y) → (x, y + 1) and moving down is (x, y) → (x + 1, y). The goal is to determine the
maximum number of coins the player can collect (by moving into a cell).

For example, on the m × n = 5 × 6 grid depicted 1 2 3 4 5 6


right, the player can collect 5 coins by following . . .
1 C C C
the solid-red path. This is maximum possible and
the answer is 5. A suboptimal path is depicted in 2 . # C C C #
dashed-blue, yielding 4 coins. 3 C . . . # #
4 . C # # . .

5 . C . . C .

Remark: Be careful not to peek into an element of the table that is out-of-bounds (i.e., not within [1, m] ×
[1, n]), as this can cause undefined behavior on a real computer.
(a) Write the pseudocode of a recursive function f (x, y) which takes as argument a position of the
character (x, y), and outputs the maximum number of coins that the character can collect if it
started at (x, y) (ignoring all coins it might have previously collected). For example, in the grid
above, f (1, 1) = 5, f (2, 1) = 4, f (5, 5) = 1, f (5, 6) = 0. The function does not need to be
memoized for this subtask.
(b) Prove that your algorithm terminates in finite time (even if possibly exponential in the size of the
input). Prove that the algorithm is correct.
Hint: (This hint is assuming you implemented part (a) in the most natural recursive way.) To prove the
algorithm completes in finite time, observe that x + y only increases and is bounded, hence no infinite
execution paths exist.
Hint: To prove the algorithm is correct, we simply need to prove the invariant which describes f (x, y)
(i.e., the first sentence of part (a)). Assume, by induction, the invariant holds for recursive calls f (x, y)
with strictly larger values of x + y, i.e., for those f (x′ , y ′ ) such that x′ + y ′ > x + y. Argue that
then it also holds for f (x, y) — we do this by considering the optimal path P ∗ that starts at (x, y) and

3
consider three cases: if P ∗ ends immediately, if P ∗ initially goes to the right, or it goes down. Using
the inductive hypothesis, argue that in each of those cases f (x, y) becomes a value at least as large
as the number of coins collected on P ∗ . Similarly, by considering the three cases, argue that the final
value cannot be larger than that of P ∗ since otherwise we could find a better P ∗ . This, by induction,
establishes that f (x, y) is always equal to the number of coins on P ∗ .
(c) Rewrite the pseudocode of the subtask (a), but apply memoization to the above f . Prove that calling
f (1, 1) will, in the worst-case, complete in O(m · n) time.
(d) Write the pseudocode for an algorithm that computes the solution in O(m · n) time, but does not
use any recursion. Address the following aspects of your solution:
(a) Definition of the DP table: What are the dimensions of the table DP ? What is the meaning
of each entry?
(b) Computation of an entry: How can an entry be computed from the values of other entries?
(c) Specify the base cases, i.e., the entries that do not depend on others.
(d) Calculation order: In which order can entries be computed so that values needed for each
entry have been determined in previous steps?
(e) Extracting the solution: How can the final solution be extracted once the table has been filled?
(f) Running time: What is the running time of your solution?
(g) Explicitly write out the pseudocode.

4
Eidgenössische Ecole polytechnique fédérale de Zurich
Technische Hochschule Politecnico federale di Zurigo
Zürich Federal Institute of Technology at Zurich

Departement of Computer Science 7 November 2022


Markus Püschel, David Steurer
François Hublet, Goran Zuzic, Tommaso d’Orsi, Jingqiu Ding

Algorithms & Data Structures Exercise sheet 7 HS 22

The solutions for this sheet are submitted at the beginning of the exercise class on 14 November 2022.
Exercises that are marked by ∗ are “challenge exercises”. They do not count towards bonus points.
You can use results from previous parts without solving those parts.

Exercise 7.1 k-sums (1 point).


We say that an integer n ∈ N is a k-sum if it can be written as a sum n = ak1 +· · ·+akp where a1 , . . . , ap
are distinct natural numbers, for some arbitrary p ∈ N.
For example, 36 is a 3-sum, since it can be written as 36 = 13 + 23 + 33 .
Describe a DP algorithm that, given two integers n and k, returns True if and only if n is a k-sum. Your
2
algorithm should have asymptotic runtime complexity at most O(n1+ k ).
1
Hint: The intended solution has complexity O(n1+ k ).
In your solution, address the following aspects:
1. Dimensions of the DP table: What are the dimensions of the DP table?
2. Definition of the DP table: What is the meaning of each entry?
3. Computation of an entry: How can an entry be computed from the values of other entries? Specify
the base cases, i.e., the entries that do not depend on others.
4. Calculation order: In which order can entries be computed so that values needed for each entry have
been determined in previous steps?
5. Extracting the solution: How can the solution be extracted once the table has been filled?
6. Running time: What is the running time of your solution?

Exercise 7.2 Road trip.


You are planning a road trip for your summer holidays. You want to start from city C0 , and follow
the only road that goes to city Cn from there. On this road from C0 to Cn , there are n − 1 other
cities C1 , . . . , Cn−1 that you would be interested in visiting (all cities C1 , . . . , Cn−1 are right on the
road from C0 to Cn ). For each 0 ≤ i ≤ n, the city Ci is at kilometer ki of the road for some given
0 = k0 < k1 < . . . < kn−1 < kn .
You want to decide in which cities among C1 , . . . , Cn−1 you will make an additional stop (you will stop
in C0 and Cn anyway). However, you do not want to drive more than d kilometers without making a
stop in some city, for some given value d > 0 (we assume that ki < ki−1 + d for all i ∈ [n] so that
this is satisfiable), and you also don’t want to travel backwards (so from some city Ci you can only go
forward to cities Cj with j > i).
(a) Provide a dynamic programming algorithm that computes the number of possible routes from C0
to Cn that satisfies these conditions, i.e., the number of allowed subsets of stop-cities. In order to
get full points, your algorithm should have O(n2 ) runtime.
Address the same six aspects as in Exercise 7.1 in your solution.
(b) If you know that ki > ki−1 + d/10 for every i ∈ [n], how can you turn the above algorithm into a
linear time algorithm (i.e., an algorithm that has O(n) runtime) ?

Exercise 7.3 Safe pawn lines (1 point).


On an N × M chessboard (N being the number of rows and M the number of columns), a safe pawn
line is a set of M pawns with exactly one pawn per column of the chessboard, and such that every two
pawns from adjacent columns are located diagonally to each other. When a pawn line is not safe, it is
called unsafe.
The first two chessboards below show safe pawn lines, the latter two unsafe ones. The line on the third
chessboard is unsafe because pawns d4 and e4 are located on the same row (rather than diagonally);
the line on the fourth chessboard is unsafe because pawn a5 has no diagonal neighbor at all.

6
0Z0Z0Z
5
Z0Z0Z0 5
o0Z0Z
4
0Z0o0Z 4
pZp 4
0Z0opZ 4
0Z0o0
3
o0o0o0 3
ZpZ 3
Z0o0Zp 3
Z0o0o
2
0o0Z0o 2
0Z0 2
0o0Z0Z 2
0o0Z0
1
Z0Z0Z0 1
Z0Z 1
o0Z0Z0 1
Z0Z0Z
a b c d e f a b c a b c d e f a b c d e

Describe a DP algorithm that, given N, M > 0, counts the number of safe pawn lines on an N × M
chessboard. In your solution, address the same six aspects as in Exercise 7.1. Your solution should have
complexity at most O(N M ).

Exercise 7.4 String Counting (1 point).


Given a binary string S ∈ {0, 1}n of length n, let f (S) be the length of the longest substring of con-
secutive 1s. For example f (”0110001101110001”) = 3 because the string contains ”111” (underlined)
but not ”1111”. Given n and k, the goal is to count the number of binary strings S of length n where
f (S) = k.
Write the pseudocode of an algorithm that, given positive integers n and k where k ≤ n, reports the
required answer. For full points, the running time of your solution can be any polynomial in n and k
(e.g., even O(n11 k 20 ) is acceptable).
Hint: The intended solution has complexity O(nk 2 ).
In your solution, address the same six aspects as in Exercise 7.1.

2
Exercise 7.5 Longest Snake.
You are given a game-board consisting of hexagonal fields F1 , . . . , Fn . The fields contain natural num-
bers v1 , . . . , vn ∈ N. Two fields are neighbors if they share a border. We call a sequence of fields
(Fi1 , . . . , Fik ) a snake of length k if, for j ∈ {1, . . . , k − 1}, Fij and Fij+1 are neighbors and their
values satisfy vij+1 = vij + 1. Figure ?? illustrates an example game board in which we highlighted the
longest snake.
For simplicity you can assume that Fi are represented by their indices. Also you may assume that you
know the neighbors of each field. That is, to obtain the neighbors of a field Fi you may call N (Fi ),
which will return the set of the neighbors of Fi . Each call of N takes unit time.
(a) Provide a dynamic programming algorithm that, given a game-board F1 , . . . , Fn , computes the
length of the longest snake.

11 12 3 21
10 5 3 2 20
9 4 11 1 2
1 6 5 10 9
12 13 6 7 8

Figure 1: Example of a longest snake.

Hint: Your algorithm should solve this problem using O(n log n) time, where n is the number of
hexagonal fields.
Address the same six aspects as in Exercise 7.1 in your solution.
(b) Provide an algorithm that takes as input F1 , . . . Fn and a DP table from part a) and outputs the
longest snake. If there are more than one longest snake, your algorithm can output any of them.
State the running time of your algorithm in Θ-notation in terms of n.
*(c) Find a linear time algorithm that finds the longest snake. That is, provide an O(n) time algorithm
that, given a game-board F1 , . . . , Fn , outputs the longest snake (if there are more than one longest
snake, your algorithm can output any of them).

3
Eidgenössische Ecole polytechnique fédérale de Zurich
Technische Hochschule Politecnico federale di Zurigo
Zürich Federal Institute of Technology at Zurich

Departement of Computer Science 14 November 2022


Markus Püschel, David Steurer
François Hublet, Goran Zuzic, Tommaso d’Orsi, Jingqiu Ding

Algorithms & Data Structures Exercise sheet 8 HS 22

The solutions for this sheet are submitted at the beginning of the exercise class on 21 November 2022.
Exercises that are marked by ∗ are “challenge exercises”. They do not count towards bonus points.
You can use results from previous parts without solving those parts.

Exercise 8.1 Exponential bounds for a sequence defined inductively.


Consider the sequence (an )n∈N defined by

a0 = 1,
a1 = 1,
a2 = 2,
ai = ai−1 + 2ai−2 + ai−3 ∀i ≥ 3.

The goal of this exercise is to find exponential lower and upper bounds for an .
(a) Find a constant C > 1 such that an ≤ O(C n ) and prove your statement.
(b) Find a constant c > 1 such that an ≥ Ω(cn ) and prove your statement.
Remark. One can actually show that an = Θ(φn ), where φ ≈ 2.148 is the unique positive solution
of the equation x3 = x2 + 2x + 1.

Exercise 8.2 AVL trees (1 point).


(a) Draw the tree obtained by inserting the keys 1, 6, 8, 0, 3, 2, 9 in this order into an initially empty
AVL tree. Give also the intermediate states before and after each rotation that is performed during
the process.
(b) Delete 0, 2, and 1 in this tree, and afterwards delete key 6 in the resulting tree. Give also the
intermediate states before and after each rotation is performed during the process.

Exercise 8.3 Augmented Binary Search Tree.


Consider a variation of a binary search tree, where each node has an additional member variable called
size. The purpose of the variable size is to indicate the size of the subtree rooted at this node. An
example of an augmented binary search tree (with integer data) can be seen below (Fig. 1).
a) What is the relation between the size of a node and the sizes of its children?
Hint: Consider the longest simple path in G. Prove that its endpoint is a leaf.
10
size=7

7 12
size=4 size=2

3 8 15
size=1 size=2 size=1

9
size=1

Figure 1: Augmented binary search tree

b) Describe in pseudo-code an algorithm VerifySizes(root) that returns true if all the sizes in the
tree are correct, and returns false otherwise. For example, it should return true given the tree in
Fig. 1, but false given the tree in Fig. 2.
What is the running time of your algorithm? Justify your answer.

10
size=7

7 12
size=4 size=5

3 8 15
size=1 size=2 size=1

9
size=1

Figure 2: Augmented binary search tree with buggy size: incorrect size for node with data “12”

c) Suppose we have an augmented AVL tree (i.e., as above, each node has a size member variable).
Describe in pseudo-code an algorithm Select(root, k) which, given an augmented AVL tree and
an integer k, returns the k-th smallest element in the tree in O(log n) time.

2
Example: Given the tree in Fig. 1, for k = 3, Select returns 8; for k = 5, it returns 10; for k = 1, it
returns 3; etc.
d)* To maintain the correct sizes for each node, we have to modify the AVL tree operations, insert
and remove. For this problem, we will consider only the modifications to the AVL-insert method
(i.e., you are not responsible for AVL-remove). Recall that AVL-insert first uses regular insert for
binary search trees, and then balances the tree if necessary via rotations.
• How should we update insert to maintain correct sizes for nodes?
During the balancing phase, AVL-insert performs rotations. Describe what updates need to be
made to the sizes of the nodes. (It is sufficient to describe the updates for left rotations, as right
rotations can be treated analogously.)

Exercise 8.4 Round and square brackets.


A string of characters on the alphabet {A, . . . , Z, (, ), [, ]} is called well-formed if either
1. It does not contain any brackets, or
2. It can be obtained from an empty string by performing a sequence of the following operations,
in any order and with an arbitrary number of repetitions:
(a) Take two non-empty well-formed strings a and b and concatenate them to obtain ab,
(b) Take a well-formed string a and add a pair of round brackets around it to obtain (a),
(c) Take a well-formed string a and add a pair of square brackets around it to obtain [a].
The above reflects the intuitive definition that all brackets in the string are ‘matched’ by a bracket of the
same type. For example, s = FOO(BAR[A]), is well-formed, since it is the concatenation of s1 = FOO,
which is well-formed by 1., and s2 = (BAR[A]), which is also well-formed. String s2 is well-formed
because it is obtained by operation 2(b) from s3 = BAR[A], which is well-formed as the concatenation
of well-formed strings s4 = BAR (by 1.) and s5 = [A] (by 2(c) and 1.). String t = FOO[(BAR]) is not
well-formed, since there is no way to obtain it from the above rules. Indeed, to be able to insert the
only pair of square brackets according to the rules, its content t1 = (BAR must be well-formed, but this
is impossible since t1 contains only one bracket.
Provide an algorithm that determines whether a string of characters is well-formed. Justify briefly why
your algorithm is correct, and provide a precise analysis of its complexity.
Hint: Use a data structure from the last lecture.

Exercise 8.5 Computing with a stack (2 points).


In many programming languages, e.g., in Python, stacks are commonly used for evaluating arithmetic
expressions. Evaluating expressions usually happens in two steps. First, values are loaded into the
stack. Then, operations are applied stepwise on the top elements in order to obtain the desired value.

3
7

Figure 3: A stack S0 containing the numbers 4, 3, 2, and 7 (7 is the top of the stack)

In this exercise, we focus on the second phase, and consider the following three basic operations used
to compute with stacks:
pop: If there is at least one element in the stack, remove the top element of the stack. Otherwise, do
nothing.
add: If there are at least two elements in the stack, remove the top two elements, compute their sum,
and push this sum back into the stack. If there is less than two elements in the stack, do nothing.
mul: If there are at least two elements in the stack, remove the top two elements, compute their prod-
uct, and push this product back into the stack. If there is less than two elements in the stack, do
nothing.
Below are examples of applications of pop, add, and mul.

7 7 7

2 → 2 2 → 9 2 → 14

3 3 3 3 3 3

4 4 4 4 4 4

(a) pop (remove 7) (b) add (7 + 2 = 9) (c) mul (7 · 2 = 14)

We say that an integer i can be computed from a stack S if and only if there exists a sequence of pop, add,
and mul operations on S that ends with i on top of the stack. For example, the value (3 · 2) + 4 = 10
can be computed from the stack S0 above through the following sequence of operations:

4
7

pop mul add


2 → 2 → →

3 3 6

4 4 4 10

Figure 5: Computing 10 from S0

Given a stack S containing n integers S1 , . . . , Sn ∈ {1, . . . , k} (with S1 being the top of the stack) and
an integer c, you are tasked to design a DP algorithm which determines if c can be computed from S.
To obtain full points, your algorithm should have complexity at most O(c · n), but partial points will
be awarded for any solution running in time O(k n · n).
In your solution, address the following aspects:
1. Dimensions of the DP table: What are the dimensions of the DP table?
2. Definition of the DP table: What is the meaning of each entry?
3. Computation of an entry: How can an entry be computed from the values of other entries? Specify
the base cases, i.e., the entries that do not depend on others.
4. Calculation order: In which order can entries be computed so that values needed for each entry have
been determined in previous steps?
5. Extracting the solution: How can the solution be extracted once the table has been filled?
6. Running time: What is the running time of your solution?

(*) Challenge question: Extend your algorithm to support the following additional operation:
neg: If there is at least one element in the stack, remove the top element x of the stack, and push −x
back into the stack. Otherwise, do nothing.

5
Eidgenössische Ecole polytechnique fédérale de Zurich
Technische Hochschule Politecnico federale di Zurigo
Zürich Federal Institute of Technology at Zurich

Departement of Computer Science 21 November 2022


Markus Püschel, David Steurer
François Hublet, Goran Zuzic, Tommaso d’Orsi, Jingqiu Ding

Algorithms & Data Structures Exercise sheet 9 HS 22

The solutions for this sheet are submitted at the beginning of the exercise class on 28 November 2022.
Exercises that are marked by ∗ are “challenge exercises”. They do not count towards bonus points.
You can use results from previous parts without solving those parts.

Exercise 9.1 Party & Beer & Party & Beer.


For your birthday, you organize a party and invite some friends over at your place. Some of your friends
bring their partners, and it turns out that in the end everybody (including yourself) knows exactly 7
other people at the party (note that the relation of knowing someone is commutative, i.e. if you know
someone then this person also knows you and vice versa). Show that there must be an even number of
people at your party.

Exercise 9.2 Transitive graphs (1 point).


We say that a graph G = (V, E) is
• transitive when, for any two edges {u, v} and {v, w} in E, the edge {u, w} is also in E;
• complete when its set of edges is {{u, v} | u, v ∈ V, u 6= v};
• the disjoint sum of G1 = (V1 , E1 ), . . . , Gk = (Vk , Ek ) iff V = V1 ∪ · · · ∪ Vk , E = E1 ∪ · · · ∪ Ek ,
and the (Vi )1≤i≤k are pairwise disjoint.
Show that a graph is transitive if, and only if, it is a disjoint sum of complete graphs.

Exercise 9.3 Star search, reloaded (1 point).


A star in an undirected graph G = (V, E) is a vertex that is adjacent to all other vertices. More formally,
v ∈ V is a star if and only if {{v, w} | w ∈ V \ {v}} ⊆ E.
In this exercise, we want to find a star in a graph G by walking through it. Initially, we are located at
some vertex v0 ∈ V . Each vertex has an associated flag (a Boolean) that is initially set to False. We
have access to the following constant-time operations:
• countNeighbors() returns the number of neighbors of the current vertex
• moveTo(i) moves us to the ith neighbor of the current vertex, where i ∈ {1..countNeighbors()}
• setFlag() sets the flag of the current vertex to True
• isSet() returns the value of the flag of the current vertex
• undo() undoes the latest action performed(the movement or the setting of last flag)
Assume that G has exactly one star and |G| = n. Give the pseudocode of an algorithm that finds the
star, i.e., your algorithm should always terminate in a configuration where the current vertex is a star
in G. To obtain full points, your algorithm must have complexity O(|V | + |E|), and must not introduce
any additional datastructures (no sets, no lists etc.). Show that your algorithm is correct and prove its
complexity. The behavior of your algorithm on graphs that do not contain a star can be disregarded.

Exercise 9.4 Domino.


(a) A domino set consists of all possible 62 + 6 = 21 different tiles of the form [x|y], where x and y


are numbers from {1, 2, 3, 4, 5, 6}. The tiles are symmetric, so [x|y] and [y|x] is the same tile and
appears only once.
Show that it is impossible to form a line of all 21 tiles such that the adjacent numbers of any
consecutive tiles coincide.

(b) What happens if we replace 6 by an arbitrary n ≥ 2? For which n is it possible to line up all n

2 +n
different tiles along a line?

Exercise 9.5 Introduction to Trees (1 point).


We start with a few definitions:
Definition 1. Let G = (V, E) be a graph.
• A sequence of vertices (v0 , v1 , . . . , vk ) (with vi ∈ V for all i) is a simple path iff all the vertices
are distinct (i.e., vi 6= vj for 0 ≤ i < j ≤ k) and {vi , vi+1 } is an edge for each 0 ≤ i ≤ k − 1. We
say that v0 and vk are the endpoints of the path.
• A sequence of vertices (v0 , v1 , . . . , vk ) (with vi ∈ V for all i) is a simple cycle iff (1) v0 = vk ,
(2) all other vertices are distinct (i.e., vi 6= vj for 0 ≤ i < j < k), and (3) {vi , vi+1 } is an edge for
each 0 ≤ i ≤ k − 1.
• A graph G is connected iff for every two vertices u, v ∈ V there exists a simple path with
endpoints u and v.
• A graph G is a tree iff it is connected and has no simple cycles.
In this exercise the goal is to prove a few basic properties of trees.
(a) A leaf is a vertex with degree 1. Prove that in every tree G there exists a leaf.
Hint: Consider the longest simple path in G. Prove that its endpoint is a leaf.
(b) Prove that every tree with n vertices has exactly n − 1 edges.
Hint: Prove by using induction on n. In the inductive step, use part (a) to find a leaf. Disconnect the
leaf from the tree and argue the remaining subgraph is also a tree. Apply the inductive hypothesis and
conclude.
(c) Prove that a graph with n vertices is a tree iff it has n − 1 edges and is connected.

2
Hint: One direction is immediate by part (c). For the other direction (every connected graph with n − 1
edges is a tree), use induction on n. First, prove there always exists a leaf by considering the average
degree. Then, disconnect the leaf from the graph and argue the remaining graph is still connected and
has exactly one less edge. Apply the inductive hypothesis and conclude.
(d) Write the pseudocode of an algorithm that is given a graph G as input and checks whether G is a
tree.
As input, you can assume that the algorithm has access to the number of vertices n, the number
of edges m, and to the edges {a1 , b1 }, {a2 , b2 }, . . . , {am , bm } (i.e., the algorithm has access to 2m
integers a1 , . . . , am , b1 , . . . , bm , where each edge of G is given by its endpoints ai and bi ). You can
assume that the graph is valid (specifically, 1 ≤ ai , bi ≤ n and ai 6= bi ). The algorithm outputs
“YES” or “NO”, corresponding to whether G is a tree or not. Your algorithm must always complete
in time polynomial in n (e.g., even O(n10 m10 ) suffices).
Hint: Use part (c). There exists a (relatively) simple O(n + m) solution. However, the official solution
is O(n · m) for brevity and uses recursion to check if G is connected.

Example 1: n = 6 3 Output: YES


m=5
a1 , b1 = 1, 3
a2 , b2 = 6, 1 1 5 2
a3 , b3 = 3, 5
a4 , b4 = 2, 3
a5 , b5 = 4, 1 6 4

Example 2: n = 5 Output: NO
m=4 4 5
a1 , b1 = 1, 3
a2 , b2 = 4, 5
2
a3 , b3 = 5, 2
a4 , b4 = 2, 4
3 1

3
Eidgenössische Ecole polytechnique fédérale de Zurich
Technische Hochschule Politecnico federale di Zurigo
Zürich Federal Institute of Technology at Zurich

Departement of Computer Science 28 November 2022


Markus Püschel, David Steurer
François Hublet, Goran Zuzic, Tommaso d’Orsi, Jingqiu Ding

Algorithms & Data Structures Exercise sheet 10 HS 22

The solutions for this sheet are submitted at the beginning of the exercise class on 5 December 2022.
Exercises that are marked by ∗ are “challenge exercises”. They do not count towards bonus points.
You can use results from previous parts without solving those parts.

Exercise 10.1 Depth-First Search (1 point).


Execute a depth-first search (Tiefensuche) on the following graph starting from vertex A. Use the algo-
rithm presented in the lecture. When processing the neighbors of a vertex, process them in alphabetical
order.

T
B A
F

T
B T
D E F
T
T
C

C G H
T

(a) Mark the edges that belong to the depth-first tree (Tiefensuchbaum) with a “T” (for tree edge).
(b) For each vertex in the depth-first tree, give its pre- and post-number.
(c) Give the vertex ordering that results from sorting the vertices by pre-number. Give the vertex
ordering that results from sorting the vertices by post-number.
(d) Mark every forward edge (Vorwärtskante) with an “F”, every backward edge (Rückwärtskante) with
an “B”, and every cross edge (Querkante) with a “C”.
(e) Does the above graph have a topological ordering? How can we use the above execution of depth-
first search to find a directed cycle?
(f) Draw a scale from 1 to 16, and mark for every vertex v the interval Iv from pre-number to post-
number of v. What does it mean if Iu ⊂ Iv for two different vertices u and v?
(g) Consider the graph above where the edge from E to D is removed and an edge from A to H is
added. How does the execution of depth-first search change? Which topological sorting does the
depth-first search give? If you sort the vertices by pre-number, does this give a topological sorting?

Exercise 10.2 Longest path in DAGs (1 point).


Given a directed graph G = (V, E) without directed cycles (i.e., a DAG), the goal is to find the number
of edges on the longest path in G.
Describe a dynamic-programming algorithm that, given G, returns the length of the longest path in G
in O(|V | + |E|) time. You can assume that V = {1, 2, . . . , n}, and that the graph is provided to you
as a pair (n, Adj) of an integer n = |V | and an adjacency list Adj. Your algorithm can access Adj[u],
which is a list of vertices to which u has a direct edge, in constant time. Formally, Adj[u] := {v ∈ V |
(u, v) ∈ E}.

Example: n = 5 1 2 Output: 3
(the path is highlighted in red.)
3

In your solution, address the following aspects:


1. Dimensions of the DP table: What are the dimensions of the DP table?
2. Definition of the DP table: What is the meaning of each entry?
3. Computation of an entry: How can an entry be computed from the values of other entries? Specify
the base cases, i.e., the entries that do not depend on others.
4. Calculation order: In which order can entries be computed so that values needed for each entry have
been determined in previous steps?
5. Extracting the solution: How can the solution be extracted once the table has been filled?
6. Running time: What is the running time of your solution?

Exercise 10.3 Subtree sum (1 point).


~ we define its undirected version as ←
~ = (V, E)
Definition 1. Given a directed graph G
→ ←

G = (V, E )


with each directed edge u → v being transformed to an undirected u ↔ v. Formally, E := ({u, v} |
~
(u, v) ∈ E}.
←→
Definition 2. A directed graph G = (V, E) is a tree rooted at r ∈ V if G’s undirected version G is
an undirected tree (see Exercise 9.5 for a definition) and every node is reachable from r via a directed
path.
Write the pseudocode of an algorithm that, given a rooted tree G = (V, E), computes, for each vertex
v, the total number of vertices that are reachable from v (via directed paths). The algorithm should have
a runtime of O(|V | + |E|). You an assume V = {1, 2, . . . , n}. The graph will be given to the algorithm
as access to n, the root r ∈ V , and an adjacency list. Namely, the algorithm can access Adj[u], which
is a list of vertices to which u has a direct edge. Formally, Adj[u] := {v ∈ V | (u, v) ∈ E}.

2
Explain in a few sentences why your algorithm achieves the desired runtime.
Hint: If needed, you can use the fact that “in G, there is a unique path from the root to each vertex” without
proof.

Example: 3 Output: [3, 1, 6, 1, 1, 1].


n=6
r=3
1 5 2

6 4

Exercise 10.4 Data structures for graphs.


Consider three types of data structures for storing a graph G with n vertices and m edges:
a) Adjacency matrix.
b) Adjacency lists:
1 2 3 4 5
2 4 1 6
3 1
4 5 2 1
5 4 1
6 2

c) Adjacency lists, and additionally we store the degree of each node, and there are pointers between
the two occurences of each edge. (An edge appears in the adjacency list of each endpoint).
1 deg: 4 2 3 4 5

2 deg: 3 4 1 6
3 deg: 1
1
4 deg: 3
5 2 1
5 deg: 2 4 1
6 deg: 1
2

For each of the above data structures, what is the required memory (in Θ-Notation)?
Which runtime (worst case, in Θ-Notation) do we have for the following queries? Give your answer
depending on n, m, and/or deg(u) and deg(v) (if applicable).
(a) Input: A vertex v ∈ V . Find deg(v).
(b) Input: A vertex v ∈ V . Find a neighbour of v (if a neighbour exists).
(c) Input: Two vertices u, v ∈ V . Decide whether u and v are adjacent.
(d) Input: Two adjacent vertices u, v ∈ V . Delete the edge e = {u, v} from the graph.

3
(e) Input: A vertex u ∈ V . Find a neighbor v ∈ V of u and delete the edge {u, v} from the graph.
(f) Input: Two vertices u, v ∈ V with u 6= v. Insert an edge {u, v} into the graph if it does not exist
yet. Otherwise do nothing.
(g) Input: A vertex v ∈ V . Delete v and all incident edges from the graph.
For the last two queries, describe your algorithm.

Exercise 10.5 Maze solver.


You are given a maze that is described by a n × n grid of blocked and unblocked cells (see Figure ??).
There is one start cell marked with ’S’ and one target cell marked with ’T’. Starting from the start cell
your algorithm may traverse the maze by moving from unblocked fields to adjacent unblocked fields.
The goal of this exercise is to devise an algorithm that given a maze returns the best solution (traversal
from ’S’ to ’T’) of the maze. The best solution is the one that requires the least moves between adjacent
fields.
Hint: You may assume that there always exists at least one unblocked path from ’S’ to ’T’ in a maze.

Figure 1: An example of 7 × 7 maze in which purple fields are blocked, white fields can be traversed
(are unblocked). The start field is marked with ’S’ and the target field with a ’T’.

(a) Model the problem as a graph problem. Describe the set of vertices V and the set of edges E in
words. Reformulate the problem description as a graph problem on the resulting graph.
(b) Choose a data structure to represent your maze-graphs and use an algorithm discussed in the lecture
to solve the problem.
Hint: If there are multiple solutions of the same quality, return any one of them.
(c) Determine the running time and memory requirements of your algorithm in terms of n in Θ nota-
tion.

4
Eidgenössische Ecole polytechnique fédérale de Zurich
Technische Hochschule Politecnico federale di Zurigo
Zürich Federal Institute of Technology at Zurich

Departement of Computer Science 5 December 2022


Markus Püschel, David Steurer
François Hublet, Goran Zuzic, Tommaso d’Orsi, Jingqiu Ding

Algorithms & Data Structures Exercise sheet 11 HS 22

The solutions for this sheet are submitted at the beginning of the exercise class on 12 December 2022.
Exercises that are marked by ∗ are “challenge exercises”. They do not count towards bonus points.
You can use results from previous parts without solving those parts.

Exercise 11.1 Shortest paths by hand.


Dijkstra’s algorithm allows to find shortest paths in a directed graph when all edge costs are nonnega-
tive. Here is a pseudo-code for that algorithm:

Algorithm 1
Input: a weighted graph, represeted via c(·, ·). Specifically, for two vertices u, v the value c(u, v)
represents the cost of an edge from u to v (or ∞ if no such edge exists).
function Dijkstra(G, s)
d[s] ← 0 . upper bounds on distances from s
d[v] ← ∞ for all v 6= s
S←∅ . set of vertices with known distances
while S 6= V do
choose v ∗ ∈ V \ S with minimum upper bound d[v ∗ ]
add v ∗ to S
update upper bounds for all v ∈ V \ S:
d[v] ← minpredecessor u∈S of v d[u] + c(u, v)
(if v has no predecessors in S, this minimum is ∞)

We remark that this version of Dijkstra’s algorithm focuses on illustrating how the algorithm explores
the graph and why it correctly computes all distances from s. You can use this version of Dijkstra’s
algorithm to solve this exercise.
In order to achieve the best possible running time, it is important to use an appropriate data structure
for efficiently maintaining the upper bounds d[v] with v ∈ V \S, as you saw in the lecture on December
1. In the other exercises/sheets and in the exam you should use the running time of the efficient version
of the algorithm (and not the running time of the pseudocode described above).
Consider the following weighted directed graph:
s
3
5
a 10 b
1
5
8 c 1
3
9
d e
2

a) Execute the Dijkstra’s algorithm described above by hand to find a shortest path from s to each
vertex in the graph. After each step (i.e. after each choice of v ∗ ), write down:
1) the upper bounds d[u], for u ∈ V , between s and each vertex u computed so far,
2) the set M of all vertices for which the minimal distance has been correctly computed so far,
3) and the predecessor p(u) for each vertex in M .
b) Change the weight of the edge (a, c) from 1 to −1 and execute Dijkstra’s algorithm on the new
graph. Does the algorithm work correctly (are all distances computed correctly) ? In case it breaks,
where does it break?
c) Now, additionally change the weight of the edge (e, b) from 1 to −6 (so edges (a, c) and (e, b) now
have negative weights). Show that in this case the algorithm doesn’t work correctly, i.e. there exists
some u ∈ V such that d[u] is not equal to a minimal distance from s to u after the execution of the
algorithm.

Exercise 11.2 Depth-First Search Revisited (1 point).


In this exercise we examine the depth-first search in a graph G = (V, E), printed here for convenience.
For concreteness, you can assume that V = {1, . . . , n} and that for v ∈ V we have access to an
adjacency list adj[v].

2
Algorithm 2
Input: graph G, given as adj and n ≥ 1.
Global variable: marked[1 . . . n], initialized to [F alse, F alse, . . . , F alse].
Global variable: T , initialized to T ← 1.
Global variable: pre[1 . . . n]. . Pre-order number.
Global variable: post[1 . . . n]. . Post-order number.

function DF S(v)
marked[v] ← T rue
pre[v] ← T
T ←T +1
for each neighbor w ∈ adj[v] do
if not marked[w] then
DF S(w)
post[v] ← T
T ←T +1

for v ∈ {1, . . . , n} do
if not marked[v] then
DF S(v)

(a) Consider the graphical representation of the DFS order where a vertex v is represented as an interval
[pre(v), post(v)]. Give a short argument why in directed or undirected graphs no two such intervals
can intersect without one being fully contained in the other. Specifically, argue why the situation
depicted in the figure below cannot happen.

pre(b) post(b)

pre(a) post(a)

(b) Give a short argument why undirected graphs cannot have any cross edges.
(c) Prove that a directed graph is acyclic (i.e., a DAG) if and only if it has no back edges. This was
proven in the lecture, but the goal here is to explicitly write out the entire argument.
Hint: You need to prove both directions of the equivalence.
Hint: For the ( =⇒ ) direction, assume the opposite (there is a back edge), then simply find a cycle
containing that back edge. If needed, you can use without proof the property that if the interval of a is
contained within interval b, then there exists a simple path from b to a.
Hint: For the ( ⇐= ) direction, we need to prove the graph is a DAG (i.e., acyclic). It is sufficient to
find a topological ordering such that all directed edges originate at vertices that are before their tail
(according to the ordering). One specific order that works is the reverse post-order.

Exercise 11.3 Language Hiking (2 points).


Alice loves both hiking and learning new languages. Since she moved to Switzerland, she has always
wanted to discover all four language regions of the country in a single hike – but she is not sure whether
her week of vacation will be sufficient.

3
You are given a graph G = (V, E) representing the towns of Switzerland. Each vertex V corresponds
to a town, and there is an (undirected) edge {v1 , v2 } ∈ E if and only if there exists a direct road going
from town v1 to town v2 . Additionally, there is a function w : E → N such that w(e) corresponds to
the number of hours needed to hike over road e, and a function ` : V → {G, F, I, R} that maps each
town to the language that is spoken there1 . For simplicity, we assume that only one language is spoken
in each town.
Alice asks you to find an algorithm that returns the walking duration (in hours) of the shortest hike
that goes through at least one town speaking each of the four languages.
For example, consider the following graph, where languages appear on vertices:

G
30 6 25
12
F F G G
4
12
12 25 30 14 8 12
7 15 14 9
F G G R G
10 8
25
I
9
I

The shortest path satisfying the condition is marked in red. It goes through one R vertex, one I vertex,
two G vertices and one F vertex. Your algorithm should return the cost of this path, i.e., 40.
(a) Suppose we know the order of languages encountered in the shortest hike. It first goes from an
R vertex to an I vertex, then immediately to a G vertex, and reaches an F vertex in the end, af-
ter going through zero, one or more additional G vertices. In other terms, the form of the path
is RIGF or RIG…GF. In this case, describe an algorithm which finds the shortest path satisfying
the condition, and explain its runtime complexity. Your algorithm must have complexity at most
O((|V | + |E|) log |V |).
Hint: Consider the new vertex set V 0 = V × {1, 2, 3, 4} ∪ {vs , vd }, where vs is a ‘super source’ and
vd a ‘super destination’ vertex.
(b) Now we don’t make the assumption in (a). Describe an algorithm which finds the shortest path
satisfying the condition. Briefly explain your approach and the resulting runtime complexity. To
obtain full points, your algorithm must have complexity at most O((|V | + |E|) log |V |).
Hint: Consider the new vertex set V 0 = V × {0, 1}4 ∪ {vs , vd }, where vs is a ‘super source’ and vd a
‘super destination’ vertex.

1
G, F, I and R stand for German, French, Italian, and Romansh respectively.

4
Eidgenössische Ecole polytechnique fédérale de Zurich
Technische Hochschule Politecnico federale di Zurigo
Zürich Federal Institute of Technology at Zurich

Departement of Computer Science 12 December 2022


Markus Püschel, David Steurer
François Hublet, Goran Zuzic, Tommaso d’Orsi, Jingqiu Ding

Algorithms & Data Structures Exercise sheet 12 HS 22

The solutions for this sheet are submitted at the beginning of the exercise class on 19 December 2022.
Exercises that are marked by ∗ are “challenge exercises”. They do not count towards bonus points.
You can use results from previous parts without solving those parts.

Exercise 12.1 MST practice.


Consider the following graph

a
6
8

b 7 c
10
1

4 d 3
2
12
e f
5

a) Compute the minimum spanning tree (MST) using Boruvka’s algorithm. For each step, provide the
set of edges that are added to the MST.
b) Provide the order in which Kruskal’s algorithm adds the edges to the MST.
c) Provide the order in which Prim’s algorithm (starting at vertex d) adds the edges to the MST.

Exercise 12.2 Maximum Spanning Trees and Trucking (2 points).


We start with a few questions about maximum spanning trees.
(a) How would you find the maximum spanning tree in a weighted graph G? Briefly explain an
algorithm with runtime O((|V | + |E|) log |V |).
(b) Given a weighted graph G = (V, E) with weights w : E → R, let G≥x = (V, {e ∈ E | w(e) ≥ x})
be the subgraph where we only preserve edges of weight x or more. Prove that for every s ∈ V, t ∈
V, x ∈ R, if s and t are connected in G≥x then they will also be connected in T≥x , where T is the
maximum spanning tree of G.
Hint: Use Kruskal’s algorithm as inspiration for the proof.
Hint: If it helps, you can assume all edges have distinct weight and only prove the claim for that case.
Problem: You are starting a truck company in a graph G = (V, E) with V = {1, 2, . . . , n}. Your
headquarters are in vertex 1 and your goal is to deliver the maximum amount of cargo to a destination
t ∈ V in a single trip. Due to local laws, each road e ∈ E has a maximum amount of cargo your truck
can be loaded with while traversing e. Find the maximum amount of cargo you can deliver for each
t ∈ V with an algorithm that runs in O((|V | + |E|) log |V |) time.
Example:

1 5 3 10 4 Output: Explanation:
Max cargo to 1 is ∞ The best path from the headquar-
10 8 Max cargo to 2 is 10 ters to 4 is 1 → 2 → 3 → 4, and
Max cargo to 3 is 8 the maximum cargo the truck
2 Max cargo to 4 is 8 can carry is min(10, 8, 10) = 8.

(c) Prove that for every t ∈ V , the optimal route is to take the unique path in the maximum spanning
tree of G.
Hint: Suppose that the largest amount of cargo we can carry from 1 to t in G (i.e., the correct result)
is OP T and let ALG be the largest amount of cargo from 1 to t in the maximum spanning tree. We
need to prove two directions: OP T ≤ ALG and OP T ≥ ALG.
Hint: One direction holds trivially as any spanning tree is a subgraph. For the other direction, use part
(b).
(d) Write the pseudocode of the algorithm that computes the output for all t ∈ V and runs in O((|V | +
|E|) log |V |). You can assume that you have access to a function that computes the maximum
spanning tree from G and outputs it in any standard format. Briefly explain why the runtime
bound holds.

Exercise 12.3 Counting Minimum Spanning Trees With Identical Edge Weights (1 point).
Let G = (V, E) be an undirected, weighted graph with weight function w.
It can be proven that, if G is connected and all its edge weights are pairwise distinct1 , then its Minimum
Spanning Tree is unique. You can use this fact without proof in the rest of this exercise.
For k ≥ 0, we say that G is k-redundant if k of G’s edge weights are non-unique, e.g.

|{e ∈ E | ∃e0 ∈ E. e 6= e0 ∧ w(e) = w(e0 )}| = k.

In particular, if G’s edge weights are all distinct, then G is 0-redundant, and if its edge weights are all
identical, it is |E|-redundant.
(a) Given a weighted graph G = (V, E) with weight function c and e = {v, w} ∈ E, we say that we
contract e when we perform the following operations:
(i) Replace v and w by a single vertex vw in V , i.e., V 0 ← V − {v, w} ∪ {vw}.
1
I.e., for all e 6= e0 ∈ E, w(e) 6= w(e0 ).

2
(ii) Replace any edge {v, x} or {w, x} by an edge {vw, x} in E, i.e.,

E 0 ← E − {{v, x} | x ∈ V } − {{w, x} | x ∈ V } ∪ {{vw, x} | {v, x} ∈ E ∨ {w, x} ∈ E}.

(iii) Set the weight of the new edges to the weight of the original edges, taking the minimum of
the two weights if two edges are merged, i.e.

c0 ({x, y}) = c({x, y}) x, y ∈


/ {v, w}
0
c ({vw, x}) = c({v, x}) {v, x} ∈ E, {w, x} ∈
/E
0
c ({vw, x}) = c({w, x}) {v, x} ∈
/ E, {w, x} ∈ E
0
c ({vw, x}) = min(c({v, x}), c({w, x})) {v, x} ∈ E, {w, x} ∈ E.

For all G = (V, E) and e ∈ E, we denote by Ge the graph obtained by contracting e in G. Explain
why if T is an MST of G and e ∈ T , then Te must be an MST of Ge .
(b) Let k > 0. Show that for all k-redundant G = (V, E) and e 6= e0 ∈ E with w(e) = w(e0 ), then Ge
is k 0 -redundant for some k 0 ≤ k − 1.
(c) Show that if G is connected and k-redundant, it has at most 2k distinct MSTs.
Hint: By induction over k, using (a) and (b).
(d) Show that for all large enough n, there exists a graph G such that G is n-redundant and has at least
n
2 2 distinct MSTs.
Hint: First assume that n = 3k for some k. Consider graphs of the following form, where all unmarked
edges have weight 0. When n = 3k + 1 or n = 3k + 2, you can add one or two edges with cost 0 at
either end.
• • • •

• •
1
• •
2
• •
3 . . . k − 1• •

3
Eidgenössische Ecole polytechnique fédérale de Zurich
Technische Hochschule Politecnico federale di Zurigo
Zürich Federal Institute of Technology at Zurich

Departement of Computer Science 19 December 2021


Markus Püschel, David Steurer
François Hublet, Goran Zuzic, Tommaso d’Orsi, Jingqiu Ding

Algorithms & Data Structures Homework 13 HS 22

Exercise Class (Room & TA):


Submitted by:
Peer Feedback by:
Points:

Submission: This exercise sheet is not to be turned in. The solutions will be published at the end of
the week, before Christmas.
Exercise 13.1 Shortest path with negative edge weights (part I).
Let G = (V, E, w) be a graph with edge weights w : E → Z \ {0} and wmin = mine∈E w(e).
Since Dijkstra’s algorithm must not be used whenever some edge weights are negative (i.e., wmin < 0),
one could come up with the idea of applying a transformation to the edge weight of every edge e ∈ E,
namely w0 (e) = w(e) − wmin + 1, such that all weights become positive, and then find a shortest path
P in G by running Dijkstra with these new edge weights w0 .
Show that this is not a good idea by providing an example graph G with a weight function w, such
that the above approach finds a path P that is not a shortest path in G (this path P can start from the
vertex of your choice). The example graph should have exactly 5 nodes and not all weights should be
negative.

Exercise 13.2 Shortest path with negative edge weights (part II).
We consider the following graph:

6
1 2
4
2 1 5
3 1

1 4 -4 2 5

3 1 4

1. What is the length of the shortest path from vertex 1 to vertex 6 ?


2. Consider Dijkstra’s algorithm (that fails here, because the graph has negative edge weights).
Which path length from vertex 1 to vertex 6 is Dijkstra computing? State the sets S, V \ S im-
mediately before Dijkstra is making its first error and explain in words what goes wrong.
3. Which efficient algorithm can be used to compute a shortest path from vertex 1 to vertex 6 in the
given graph? What is the running time of this algorithm in general, expressed in n, the number
of vertices, and m, the number of edges ?
4. On the given graph, execute the algorithm by Floyd and Warshall to find all shortest paths. Ex-
press all entries of the (6 × 6 × 7)-table as 7 tables of size 6 × 6. (It is enough to state the path
length in the entry without the predecessor vertex.) Mark the entries in the table in which one
can see that the graph does not contain a negative cycle.

Exercise 13.3 Invariant and correctness of algorithm (This exercise is from the January 2020 ex-
am).
Given is a weighted directed acyclic graph G = (V, E, w), where V = {1, . . . , n}. The goal is to find
the length of the longest path in G.
Let’s fix some topological ordering of G and consider the array top[1, . . . , n] such that top[i] is a vertex
that is on the i-th position in the topological ordering.
Consider the following pseudocode

Algorithm 1 Find-length-of-longest-path(G, top)


L[1], . . . , L[n] ← 0, . . . , 0
for i = 1, . . . , n do
v ← top[i]  
L[v] ← max L[u] + w (u, v)
(u,v)∈E

return max L[i]


1≤i≤n

Here we assume that maximum over the empty set is 0.


Show that the pseudocode above satisfies the following loop invariant INV(k) for 1 ≤ k ≤ n: After k
iterations of the for-loop, L[top[j]] contains the length of the longest path that ends with top[j] for all
1 ≤ j ≤ k.
Specifically, prove the following 3 assertions:
i) INV(1) holds.
ii) If INV(k) holds, then INV(k + 1) holds (for all 1 ≤ k < n).
iii) INV(n) implies that the algorithm correctly computes the length of the longest path.

State the running time of the algorithm described above in Θ-notation in terms of |V | and |E|. Justify
your answer.

Exercise 13.4 Cheap flights (This exercise is from the January 2020 exam).

2
Suppose that there are n airports in the country Examistan. Between some of them there are direct
flights. For each airport there exists at least one direct flight from this airport to some other airport.
Totally there are m different direct flights between the airports of Examistan.
For each direct flight you know its cost. The cost of each flight is a strictly positive integer.
You can assume that each airport is represented by its number, i.e. the set of airports is {1, . . . , n}.

a) Model these airports, direct flights and their costs as a directed graph: give a precise description of
the vertices, the edges and the weights of the edges of the graph G = (V, E, w) involved (if possible,
in words and not formal).

In points b) and c) you can assume that the directed graph is represented by a data structure that allows
you to traverse the direct predecessors and direct successors of a vertex u in time O(deg− (u)) and
O(deg+ (u)) respectively, where deg− (u) is the in-degree of vertex u and deg+ (u) is the out-degree of
vertex u.

b) Suppose that you are at the airport S and you want to fill the array d of minimal traveling costs to
each airport. That is, for each airport A, d[A] is a minimal cost that you must pay to travel from S
to A.
Name the most efficient algorithm that was discussed in lectures which solves the corresponding
graph problem. If several such algorithms were described in lectures (with the same running time),
it is enough to name one of them. State the running time of this algorithm in Θ-notation in terms
of n and m.
c) Now you want to know how many optimal routes there are to airport T . In other words, if cmin is
the minimal cost from S to T then you want to compute the number of routes from S to T of cost
cmin .
Assume that the array d from b) is already filled. Provide an as efficient as possible dynamic pro-
gramming algorithm that takes as input the graph G from task a), the array d from point b) and the
airports S and T , and outputs the number of routes from S to T of minimal cost.
Address the following aspects in your solution and state the running time of your algorithm:
1) Definition of the DP table: What are the dimensions of the table DP [. . .] ? What is the meaning
of each entry ?
2) Computation of an entry: How can an entry be computed from the values of other entries ?
Specify the base cases, i.e., the entries that do not depend on others.
3) Calculation order: In which order can entries be computed so that values needed for each entry
have been determined in previous steps ?
4) Extracting the solution: How can the final solution be extracted once the table has been filled ?
5) Running time: What is the running time of your algorithm ? Provide it in Θ-notation in terms
of n and m, and justify your answer.

3
Exercise 13.5 Elevator (This exercise is from the January 2022 exam).
Consider the following definitions for a directed graph G = (V, E):
1. The out-degree of a vertex v ∈ V , denoted with degout (v), is the number of edges of E that start
at v, i.e., degout (v) = |{(v, w) ∈ E | w ∈ V }|.
2. The in-degree of a vertex v ∈ V , denoted with degin (v), is the number of edges that end at v, i.e.,
degout (v) = |{(u, v) ∈ E | u ∈ V }|.
3. A Eulerian walk is a sequence v1 , . . . , vk ∈ V such that k = |E| + 1 and {(vi , vi+1 ) | 1 ≤ i <
k} = E. Note that this definition implies (vi , vi+1 ) being different edges for 1 ≤ i < k.
In this exercise, you can use without proof the following result from the lecture:

Lemma 1. A directed graph G = (V, E) admits a Eulerian walk if, and only if, all of the following
conditions holds:
1. At most one vertex v ∈ V is such that degout (v) = degin (v) + 1;
2. At most one vertex v ∈ V is such that degin (v) = degin (v) + 1;
3. Every vertex that satisfies neither (i) nor (ii) is such that degout (v) = degin (v);
4. The undirected graph G0 obtained by ignoring the direction of edges in G is connected.
a) Write down the pseudocode of an O(|V | + |E|) time algorithm that takes as input a directed graph
G, and returns true if G has a Eulerian walk, and false otherwise. Justify its correctness and
complexity.
b) Alice is launching iFahrstuhl™, a start-up developing the next generation of elevators.
Assume a building with n floors indexed from 1 to n and an elevator which has room for a single
person. The elevator receives requests in the form of pairs (i, j) ∈ {1, . . . , n}2 of distinct floors
between which a single person is willing to travel.
Consider the scenario where m people want to use the elevator. For 1 ≤ t ≤ m, the t-th people want
to go from floor it to floor jt . These requests are given as a finite set S = {(i1 , j1 ), . . . , (im , jm )}.
A finite set S = {(i1 , j1 ), . . . , (im , jm )} of requests is called optimal if the pairs can be ordered such
that all requests can be processed and the elevator is never empty when moving between two floors
(except maybe on its way to fetching the first person).
For example, for n = 5, the set S1 = {(2, 3), (4, 1), (3, 4)} is optimal, since it can ordered as
{(2, 3), (3, 4), (4, 1)}, which means that the elevator can start on floor 2 to fetch person 1, go to
floor 3, drop person 1 and fetch person 3, go to floor 4, drop person 3 and fetch person 2, go to floor
1, drop person 2, and terminate there. However, the set S2 = {(2, 3), (4, 1)} is not optimal, since
there is no way a single elevator can satisfy both requests without moving empty from floor 3 to
floor 4 or floor 1 to floor 2.
Given a set of requests S, Alice’s elevators should be able to decide whether it’s optimal. Model
the problem of detecting optimal sets of requests as a graph problem and provide an algorithm to
solve it. Describe the vertex and edge set, edge weights (if needed), the graph problem you solve,
the algorithm you use, and its complexity. To obtain full points, your algorithm should run in time
O(n + |S|).
c) Alice’s startup has installed k single-person elevators in your n-floor building. Unfortunately, not
all elevators can reach all floors. Hence, for each elevator j ∈ {1, . . . , k}, you are given a set Fj ⊆

4
{1, . . . , n} of floors it can reach. When you arrive in front of an elevator j, say on floor f ∈ Fj ,
you can immediately call it, after which you have to wait until it reaches your floor from its current
position, moving at the constant speed of 1 time unit per floor. When the elevator arrives, you choose
the destination floor f 0 ∈ Fj , and the elevator brings you to this floor at the constant speed of 0.5
time units per floor (for security reasons, the elevator is slower when it is not empty). The time spent
moving between elevators on the same floor, calling the elevator or choosing the destination floor
is negligible, since you are very fast at interacting with elevators.
You are alone in the building at floor 1, with each elevator j being initally located on floor fj . You
would like to go to floor n. What is the minimal amount of time that you have to travel using Alice’s
elevators? If you cannot reach floor n, then output ∞.
Model the problem as a graph problem and provide an algorithm to solve it. Describe the vertex
and edge set, edge weights (if needed), the graph problem you solve, the algorithm you use, and
its complexity. To obtain full points, your algorithm should run in time O((n + K) log n), where
K = pj=1 |Fj |2 .
P

d) Continue the setting of (c). Elevator doors in your building need maintenance, but the people in
your building also need elevators. In your building, there is exactly one elevator door per elevator
and floor, which needs to be functional in order for the elevator to be used from or to this floor. Even
if a door is not functional, the elevator can still be used between all other floors where a functional
door is present. Alice wants to select as many elevator doors as possible to be maintained during
the next working day such that all floors can be reached from each other using the elevators and
the remaining functional doors (those not in maintenance).
Model the problem as a graph problem and provide an algorithm to solve it. Describe the vertex
and edge set, edge weights (if needed), the graph problem you solve, the algorithm you use, and
its complexity.
PTo obtain full points, your algorithm should run in time O((n + K 0 ) log(n + K 0 )),
p
where K = j=1 |Fj |.
0

Hint: Consider the set of vertices

V = {v1 , . . . , vn } ∪ {w1 , . . . , wn } ∪ {elevator1 , . . . , elevatorj }

and use subgraphs (“gadgets”) of the form

v i1 1 wi1

1 0
v i2 wi2

0
elevatorj
... ...
0

viq 1 w iq

where Fj = {i1 , . . . , iq }.

You might also like