Week1
Week1
Q3:
Line 2 : 5 iterations
Line 3: On each iteration, O(1) because it’s a single character being printed
Total = 5*O(1) = O(1)
Q4.
a) Line 2: n iterations
Line 3: print i characters is O(i), worst case of i is n, so on each iteration
the amount of characters is at most n: O(n)
Total = n*O(n) = O(n2)
b) Asymptotically tight: the lower bound should be the same as the upper
bound, to show that the upper bound analysis was the best analysis
possible (lowest upper bound is the most informative/valuable in terms
of the true running time, and comparison between different algorithms)
How to do the analysis:
Analyse a portion of the running time and use an assumption of at least
- Start with the innermost loop first
In what interval of i does Line 3 run for at least a number of constant time
operations
Example:
i = [1,n] (interval from 1 to n) = n iterations
line 3 has at least 1 asterisk on each iteration (ie, 1 constant time operation) =
Ω(1)
total = n* Ω(1) = Ω(n)
Example 2:
i = [n/2, n] = n/2 iterations
line 3 has at least n/2 asterisks on each iteration (ie, n/2 constant time
operations) = Ω(n/2) = Ω(n)
total = (n/2)* Ω(n) = Ω(n2)
Q5.
A = [2,3,5,-2,-4,6,8]
B = [0,2,5,10,8,4,10,18]
Algorithm finds (i,j): i=0, j=6. Sum = 18
This is the optimal solution
Come up with an example to show the algorithm is incorrect
A = [100,-101,2]
B = [0,100,-1,1]
Algorithm finds: i=2, j=0, algorithm is incorrect because j must be > i
Q6.
a) Line 2: O(n2) because have to initialise n2 empty cells in the matrix with
default values
Line 3: n iterations
Line 4: at most n iterations because worst case is when i = 0
Line 5: number of additions is j-i, and addition is O(1). So this is O(n)
since worst case is i=0,j=n-1, where there are n additions in the avg
computation. Also, O(1) for division and subtraction.
Line 6: Store result = O(1) for array access
Total = O(n2)+ n*O(n)*(O(n)+O(1)) = O(n3)
b) In what interval of i and j does the avg computation run for at least a
number of constant time steps?
i = 0 = 1 iteration
j = 1 = 1 iteration
line 5 runs for 1 iteration, (j-i=1) = Ω(1)
total = 1*1* Ω(1) = Ω(1)
Even if the question doesn’t ask for it, you should always assume it
wants an asymptotically tight bound, unless specified otherwise
i = [0, 1,2,3,4,5,6,7 …. , n/2] = n/2 iterations
j = [1,2,3,4,5,6,7,8 … , n/2+1] = n/2 iterations
1-0 = 1 additions on line 5 (constant time ops)
2-0 = 1
3-0 = 1
4-0…. = 1
2-0, = 2
2-1, = 2
2-2, = 2
2-3, = 2
….
j-i > 1
condition is true, line 5 is Ω(1) in the interval
i ∈ [0,n/2] and j ∈ [1,n/2]
total = (n/2)*(n/2)* Ω(1) = Ω(n2), still not asymptotically tight
i = [0, n/2 ] = n/2 iterations
j = [ 3n/4, n ] = n/4 iterations
j-i > X condition for assumption of ‘at least’ on line5
j-i > n/4 -> line 5 is Ω(n/4) in this interval
total = (n/2)*(n/4)* Ω(n/4) = Ω(n3)
Q7.
Using preprocessing, same as in the lecture. Compute array B as a cumulative
sum, and then
C[i][j] = (B[j]-B[i-1])/(j-i+1)
We’ve replaced the previous O(n) summation on line 5 with two array access
of B and 2 subtractions, which are O(1). Time complexity reduces to O(n 2) from
O(n3)
There is O(n) additional time at the beginning to create the array B, but
this is dominated by n2
Total = O(n) + O(n2) = O(n2)
Q8.
f(n) = O(g(n))
g(n) = O(h(n))
definitions on lecture slides page 24
f(n) ≤ c * g(n)
g(n) ≤ c2 * h(n)
f(n) ≤ c * c2 * h(n)
f(n) = O(h(n)) because c*c2 is a constant
Q9.
Line 2: O(1) variable storage
Line 3: n iterations
Line 4: while loop runs for at most n because it reduces j on each iteration and
j is at most n, since it increases by 1 on each iteration of the for loop which is
bounded by n
= O(n)
Line 5: on each iteration, O(1)
Line 6: O(1) variable storage
Total = n*O(n) + O(1) = O(n2)
Actually, line 4 is not a tight analysis.
The while loop runs for at most 1 iteration, j starts at 0 so always alternates
between 0 and 1.
The tighter bound is therefore O(n)
Q10.
def consecutive_chars(A, k):
c = A[0]
counter = 1
for i in range(1,len(A)):
if A[i] == c:
counter += 1
else:
counter = 1
c = A[i]
if counter == k:
return True
return False
Q11.
Hashmap – O(n) expected time
- Count the frequency of all characters
- Check if any are > 1 frequency, there is a duplicate
Def check_duplicates(A):
Freq = {}
For e in A:
If e in Freq:
Freq[e] += 1
Else:
Freq[e] = 1
For k,v in Freq.items():
If v > 1:
Return True
Return False
Sorting – O(nlogn)
Def check_duplicates(A):
A.sort() #sort using mergesort of heapsort takes O(nlogn)
For i in range(1, len(A)):
If A[i] == A[i-1]: #check adjacent values
Return true
Return False