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

Week1

The document discusses the asymptotic analysis of algorithms, comparing logarithmic, polynomial, and exponential growth rates. It includes various questions and answers related to time complexity, providing examples and explanations for different scenarios. Additionally, it covers methods for checking duplicates in arrays and the efficiency of different approaches.

Uploaded by

Abhinav Singh
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

Week1

The document discusses the asymptotic analysis of algorithms, comparing logarithmic, polynomial, and exponential growth rates. It includes various questions and answers related to time complexity, providing examples and explanations for different scenarios. Additionally, it covers methods for checking duplicates in arrays and the efficiency of different approaches.

Uploaded by

Abhinav Singh
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 7

For a large enough value of n

Logarithms < polynomials < exponentials


log(log(n)) < logn < n^0.000001 < n^100000 < 1.0000001^n < 10000^n < n! <
n^n

Q1. Sqrt(n), n, nlogn, n3, 2n, 3n/n2, n!, nn


Q2. Smallest in asymptotic order: n1/logn
Change of base rule: logb(a) = logc(a) / logc(b)
Logn is log2n (assumption in computer science when the base is not given)
Exponent of a log of the same base cancels out
n^(1/logn) = n^(logn2/lognn) = n^logn2 = 2 = O(1)

2nd smallest in asymptotic order: loglogn


3rd smallest: 2^loglogn = logn
4th: logn!

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

Loops – O(n2) – check all combinations


Def check_duplicates(A):
For i in range(len(A)):
For j in range(i+1, len(A)):
If A[i] == A[j]:
Return True
Return False

You might also like