Tutorial 1
Tutorial 1
Tutorial 1
Big-O Notation & Pseudocode
PANG Ho Lam
PANG Ho Lam
▪ Email: hlpang@cse.cuhk.edu.hk
▪ Office: SHB 121A
▪ Office hour: Tuesday 3:30 pm – 5:30 pm
Algorithm_2_Max(array a)
max ← a[0], n ← length(a) 𝑇 𝑛 = 𝑐1 𝑛 + 𝑐2
for i ← 1 to n-1 do =𝑂 𝑛
if a[i] > max then max ← a[i]
end for
print max
Examples
Suppose a is an array of size n, say, [3, 4, 7, 1, 11, … , 8]
Algorithm_3_Loop(array a) 𝑇 𝑛 = 𝑛 𝑛 𝑐1 𝑛 + 𝑐2
for i ← 1 to n-1 do
for j ← 1 to n-1 do = 𝑂 𝑛3 = 𝑛2 𝑂 𝑛
Algorithm_2_Max(a)
Algorithm_4_Concat(array a) 𝑇 𝑛 = 𝑛 𝑛 𝑐1 𝑛 + 𝑐2 +
Algorithm_2_Max(a) 𝑐1 𝑛 + 𝑐2
Algorithm_3_Loop(a)
= 𝑂 𝑛3 = 𝑂 𝑛3 + 𝑛
Examples
Target: 10
Suppose a is a sorted array of size n
[1, 2, 4, 5, 6, 7, 8, 9]
Binary_search(array a, number target)
low ← 0
high ← length(a) [6, 7, 8, 9]
while low ≤ high do
mid ← (low + high)/2
if target>a[mid] then low ← mid+1
[8, 9]
if target<a[mid] then high ← mid-1
if target=a[mid] then [9]
print(“FOUND”)
terminate
end while 𝑇 𝑛 = 𝑐 + 𝑇 𝑛/2
print(“NOT FOUND”) = 𝑂 log 𝑛
Comparing complexities
1 2 𝑛
𝑂 1 , … , log log 𝑛 , … , log 𝑛 , log 𝑛 , … , 𝑛2 , 𝑛, 𝑛2 , … , 2𝑛 , 2𝑛 , … , 22 , …
2
▪ 𝑛1.001 = 𝑂 𝑛 log 2𝑛 ? No
▪ 𝑛3 = 𝑂 2𝑛 + 𝑛 ? Yes
Other Asymptotic Notations
▪ We may want a “lower bound” notation and a “tight bound”
notation.
2𝑛 𝑛1/3 log 𝑛 = Ω 2𝑛 𝑛1/3 log log 𝑛
▪ Big-omega, Ω
𝑛1.001 = Ω 𝑛 log 2𝑛
▪ Basically the inverse of big-o notation
▪ 𝑇 𝑛 =𝑂 𝑔 𝑛 ⟺ 𝑔 𝑛 =Ω 𝑇 𝑛
▪ Big-theta, 𝜃
▪ 𝑂+Ω
▪ 𝑇 𝑛 =𝜃 𝑔 𝑛 ⟺ 𝑇 𝑛 =𝑂 𝑔 𝑛 𝑎𝑛𝑑 𝑇 𝑛 = Ω 𝑔 𝑛
▪ 4𝑛2 + 𝑛 = 𝑂 𝑛2 , 4𝑛2 + 𝑛 = Ω 𝑛2 ⇒ 4𝑛2 + 𝑛 = 𝜃 𝑛2
Polynomial vs Exponential
▪ Algorithms running in exponential time may take hours to
complete a task, while algorithms running in polynomial time
may take seconds only.
▪ Polynomial vs Exponential in input size.
▪ In some cases, the input size is denoted by n, e.g., an n-
digit number, an array of n element, etc..
▪ In other cases, the input size is not explicitly stated.
Polynomial vs Exponential –
Fibonacci
Fibonacci (integer k)
F[0] ← 1, F[1] ← 1.
For i = 2 to k,
F[i] ← F[i-1] + F[i-2].
Output F[k].
Time complexity
𝑇 𝑘 = #𝑖𝑡𝑒𝑟𝑎𝑡𝑖𝑜𝑛𝑠 ∙ Time for each iteration
= 𝑘 ∙ Time for computing F i − 1 + F i − 2 ≈ 𝑘 ∙ 𝑂 𝑘 = 𝑂 𝑘 2 .
• In the worst case, F[i] would get one more digit after each addition.
• Adding up two i-digit numbers needs O(i) time.
Polynomial vs Exponential –
Fibonacci
Fibonacci (integer k) Input value: k
Input size: O(log k)
F[0] ← 1, F[1] ← 1.
For i = 2 to k, We need only O(log k) bits of
F[i] ← F[i-1] + F[i-2]. memory space to store integer k
Output F[k].
Time complexity
𝑇 𝑘 = #𝑖𝑡𝑒𝑟𝑎𝑡𝑖𝑜𝑛𝑠 ∙ Time for each iteration
= 𝑘 ∙ Time for computing F i − 1 + F i − 2 ≈ 𝑘 ∙ 𝑂 𝑘 = 𝑂 𝑘 2 .
Time complexity
𝑇 2𝑠 = #𝑖𝑡𝑒𝑟𝑎𝑡𝑖𝑜𝑛𝑠 ∙ Time for each iteration
= 2𝑠 ∙ Time for computing F i − 1 + F i − 2 ≈ 2𝑠 ∙ 𝑂 2𝑠 = 𝑂 22𝑠 .
Product ← 0.
For i ← 1 to y,
product ← product + x.
Output product.
Time complexity
𝑇 𝑘 = #iterations ∙ Time for each iteration
= 𝑦 ∙ Time for computing product + x = 𝑦 ∙ 𝑂 𝑛 = 2𝑛 ∙ 𝑂 𝑛 = 𝑂 2𝑛 𝑛
• Notice that this time, x, y are input values, and n is input size.
Polynomial vs Exponential –
More Confusions…
Problem 1: Given an array of n integers, find
the element with value closest to integer k.
Problem 2: Given an array of n integers, find
the k-th largest element.
Algorithm A: Solving both problems in O(nk)
time.
if a>b then
temp ← a
a ← b
b ← temp
Common Structures –
Conditional statements
▪ if B then S1 else S2 ▪ case B1
S1
▪ if B then case B2
S1 S2
else otherwise
S2 S3
endif
▪ case var of
B1: S1
B2: S2
otherwise: S3
endcase
Common Structures –
Iterations
▪ while B do S
▪ for i ← 1 to 10 do S
endfor
▪ repeat
S
until B
Examples –
Binary Search
Target: 10
Suppose a is a sorted array of size n
[1, 2, 4, 5, 6, 7, 8, 9]
Binary_search(array a, number target)
low ← 0
high ← length(a) [6, 7, 8, 9]
while low ≤ high do
mid ← (low + high)/2
if target>a[mid] then low ← mid+1
[8, 9]
if target<a[mid] then high ← mid-1
if target=a[mid] then [9]
print(“FOUND”)
terminate
end while 𝑇 𝑛 = 𝑐 + 𝑇 𝑛/2
print(“NOT FOUND”) = 𝑂 log 𝑛
Examples –
Binary Search
Suppose a is a sorted array of size n
if low>high then
print(“NOT FOUND”)
terminate
if a[mid] = target then
print(“FOUND”)
terminate
mid ← (low + high)/2
if a[mid]<target then
Call Binary_search(a, mid+1, high, target)
if a[mid]>target then
Call Binary_search(a, low, mid-1, target)
Examples –
Binary Search
Suppose a is a sorted array of size n
Observe: 13 × 7 = 6 × 14 + 7 = 3 × 28 + 7 = 1 × 56 + 35 = 91
Claim: Let 𝑥𝑖 be value stored in x in 𝑖-th iteration. For every 𝑖-th
iteration, 𝑥𝑖 × 𝑦𝑖 + 𝑝𝑖 = 𝑥 × 𝑦
Russian Peasant Method –
Proof of Correctness Russian_Peasant_2(x,y)
p ← 0
while x>0 do
if x is odd then
Claim: p ← p+y
For every 𝑖-th iteration, 𝑥𝑖 × 𝑦𝑖 + 𝑝𝑖 = 𝑥 × 𝑦 x ← x/2
y ← 2y
Mathematical Induction: end while
print p
▪ Base Step: iteration x y p
(Show claim is true for i=0) initialize 13 7 0