$\newcommand{\nfrac}[2]{\frac{\displaystyle{#1}}{\displaystyle{#2}}}$
Exercises
7.1.2
Homework.
7.1.5
We tell students sort by a single loop rather than a single-line.
def sortBySingleLoop(A[0..n-1])
# initialize a zeros list of size n
S = [0] * n
# loop on A values, Convert to corresponding index, Set that index
for i in 0..n-1
S[ A[i]-1 ] = A[i]
# S is A but sorted
return S
7.1.10
Homework.
7.2.2
Homework.
7.2.3
Homework.
7.2.11
a
Hints
- The question asks for memory. So any timely inefficient solution is acceptable.
- Use naive brute-force.
Solution
# input: strings S[0..n-1] and T[0..n-1]
# output: True if and only if T is right cyclic shift
def bruteForceRightCyclicShift(S[0..n-1], T[0..n-1])
# try all ith positions
for i in 0..n-1
# counter of matched characters
k = 0
# check from the ith position to last nth character, cycling if needed
while k < n and S[(i+k) mod n] = T[k]
k = k + 1
# all n characters are matching, i.e strings are matching
if k == n return True
# if no position matches
return False
If the mod
operation is troublesome to students, we show
# input: position x
# output:
# x if x did not pass string length n
# if x passed n, return only the additional length beyond n
def myPosition(x, n)
if x < n
return x
return x - n
# input: strings S[0..n-1] and T[0..n-1]
# output: True if and only if T is a right cyclic shift of S
def bruteForceRightCyclicShift(S[0..n-1], T[0..n-1])
# try all ith positions
for i in 0..n-1
# counter of matched characters
k = 0
# check from the ith position to last nth character, cycling if needed
while k < n and S[ myPosition(i+k,n) ] = T[k]
k = k + 1
# all n characters are matching, i.e strings are matching
if k == n return True
# if no position matches
return False
Observe greatest value of x
is $n-1 + n-1 = 2n - 2 < 2n$. So our function myPosition
is equivalent to mod
operation in this case.
Complexity. Extra space is $\mathcal{O}(1)$. Time is $\mathcal{O}(n^2)$.
b
Hints
- Use Boyer-Moore algorithm as a subroutine.
- What is the input enhancement so that a linear scan, of all possible positions, of first character, is feasible?
- Repeat the input so the check is equivalent to cycling.
Solution
# input: string S
# output: S but with n-1 prefix appended
def appendPrefix(S[0..n-1])
# copy S
X = S
# for each character of n-1 prefix
for i in 0..n-2
# append to the end
X.append( X[i] )
# return appended string
return X
# input: string S[0..n-1] and T[0..n-1]
# output: True if and only if T is a cyclic right shift of S
def BoyerMooreRightCyclicShift(S[0..n-1], T[0..n-1])
# enhance the input by appending n-1 prefix
S = appendPrefix(S)
# right cyclic shift is equivalent to matching T in enhanced input S
return BoyerMoore(S, T)
For enhanced $X$ of given input $S$, Observe $S[i \mod n] = X[i]$. In other words, our condition on the enhanced input is equivalent to the brute-force algorithm. Since we know the brute-force is correct by definition, so is BoyerMooreRightCyclicShift
.
Complexity.
- Time. $\Theta(n)$ for appending prefix. $\mathcal{O}(n)$ for Boyer-Moore algorithm (given from the levitin).
- Space. Extra space is $\Theta(n)$ for appended prefix. $\Theta(|\sum|)$ for the good-suffix table. $\Theta(n)$ for the bad-symbol table.
7.3.1
Homework.
7.3.2
Homework.
7.3.4
Given the even distribution of hash function, We have a uniform distribution. Fixing cell $c_j$ the probability of hashing to it is $Pr[R_i = c_j] = \nfrac{1}{m}$ for the ith element out of the $n$ elements. Since the hash events are pairwise independent, $Pr[C = c_j] = Pr[R_1 = c_j \wedge \dots \wedge R_n = c_j] = Pr[R_1 = c_j] \cdot .. \cdot Pr[R_n = c_j] = \left (\nfrac{1}{m} \right )^n$. Since the events of hashing all elements to a particular cell are disjoint, $Pr[C = c_0 \vee \dots \vee C_{m-1}] = Pr[C = c_0] + \dots + Pr[C = c_{m-1}] = m \left (\nfrac{1}{m} \right )^n = \nfrac{1}{m^{n-1}}$.