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

Tutorial 1

The document discusses Big-O notation and pseudocode. It provides examples of time complexities for different algorithms using Big-O notation. It also demonstrates the use of pseudocode through examples like binary search.

Uploaded by

Cyrus Li
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

Tutorial 1

The document discusses Big-O notation and pseudocode. It provides examples of time complexities for different algorithms using Big-O notation. It also demonstrates the use of pseudocode through examples like binary search.

Uploaded by

Cyrus Li
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 37

CSCI 3160

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

▪ Any question: come at my office hour, or contact me to


make an appointment.
Today’s topic
1. Big-O notation
2. Pseudocode
Big-O Notation
▪ Commonly used to express time complexity when
evaluating the performance of algorithms.
▪ We want to express running time as a function of instance
size, 𝑇 𝑛 , regardless of some hardware differences, etc..
▪ How 𝑇 𝑛 grows with 𝑛?
Big-O Notation
▪ 𝑇 𝑛 = 𝑂 𝑔 𝑛 𝑖𝑓 𝑡ℎ𝑒𝑟𝑒 𝑎𝑟𝑒 𝑠𝑜𝑚𝑒 𝑐, 𝑛0 , 𝑠𝑢𝑐ℎ 𝑡ℎ𝑎𝑡 𝑇 𝑛 ≤ 𝑐 ∙
𝑔 𝑛 𝑓𝑜𝑟 𝑎𝑙𝑙 𝑛 > 𝑛0 .
▪ (Intuitively) The growing speed of 𝑇 𝑛 is not faster than
𝑔 𝑛 .
Examples
Suppose a is an array of size n, say, [3, 4, 7, 1, 11, … , 8]
Algorithm_1_Print(array a)
if a[2]=4 then print a[2] 𝑇 𝑛 =𝑐
=𝑂 1

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

<--- faster ---- ----slower--->


▪ We compare two complexities by the above classification
and by dominating terms.
▪ Non-dominating terms are insignificant when n is large.
▪ e.g.
𝑂 4𝑛 𝑛3 > 𝑂 2𝑛 𝑛9
𝑂 4𝑛 > 𝑂 3.99𝑛 log 𝑛
Examples
▪ 2𝑛 𝑛1/3 log 𝑛 = 𝑂 2𝑛 𝑛1/3 log log 𝑛 ? No

▪ 𝑛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 .

• However… this is not polynomial time.


Polynomial vs Exponential –
Fibonacci
Fibonacci (integer 2s) Input value: up to 2s in the worst
case
F[0] ← 1, F[1] ← 1. Input size: s
For i = 2 to 2s,
F[i] ← F[i-1] + F[i-2]. We need only O(s) bits of
Output F[2s]. memory space to store integer 2s

Time complexity
𝑇 2𝑠 = #𝑖𝑡𝑒𝑟𝑎𝑡𝑖𝑜𝑛𝑠 ∙ Time for each iteration
= 2𝑠 ∙ Time for computing F i − 1 + F i − 2 ≈ 2𝑠 ∙ 𝑂 2𝑠 = 𝑂 22𝑠 .

• Time complexity is exponential in s (the input size)


Polynomial vs Exponential –
Multiplication
Product (integer x,y) * Assume x,y have n digits.

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.

Is A polynomial-time for Problem 1?

Is A polynomial-time for Problem 2?


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.

Problem 1 has input size


Is A polynomial-time for Problem 1? NO 𝑂(𝑛 + log 𝑘)

Problem 2 implies 𝑘 < 𝑛,


Is A polynomial-time for Problem 2? YES
so A runs in time 𝑂 𝑛2
Pseudocode
▪ No strict syntax.
▪ Human readable and explains idea clearly.
▪ Does not need to be very low level, unless it is implied.

if a>b then swap a and b

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

Binary_search(array a, interger low, integer high, number target)

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

Binary_search(array a, number target)

m ← the middle element of a.


If m = target, then:
Report “FOUND” and terminate the algorithm.
Else if m is the only element of a, then:
Report “NOT FOUND” and terminate the algorithm.
Else:
Split the array at m into two equal halves, a smaller
half and a larger half.
If m > target, then:
Recursively call this algorithm on the smaller half only.
If m < target, then:
Recursively call this algorithm on the larger half only.
Examples –
Binary Search
Suppose a is a sorted array of size n

Binary_search(array a, number target)

m ← the middle element of a. If m = target, then: Report “FOUND”


and terminate the algorithm. Else if m is the only element of a,
then: Report “NOT FOUND” and terminate the algorithm. Else: Split
the array at m into two equal halves, a smaller half and a larger
half. If m > target, then: Recursively call this algorithm on the
smaller half only. If m < target, then: Recursively call this
algorithm on the larger half only.

Please try to not do this!


Multiplication -
Russian Peasant Method
▪ Compute 13 × 7 = 91
x y Add
13 7
Multiplication -
Russian Peasant Method
▪ Compute 13 × 7 = 91
x y Add
13 7 7
6 14
Multiplication -
Russian Peasant Method
▪ Compute 13 × 7 = 91
x y Add
13 7 7
6 14 -
3 28
Multiplication -
Russian Peasant Method
Is x odd?
▪ Compute 13 × 7 = 91
x y Add
13 7 7 Do Do
6 14 - something something
3 28 28
1 56
Is x>1?

Repeat until x reaches 1


Add up and
output product
Multiplication -
Russian Peasant Method
Is x odd?
Russian_Peasant_1(x,y)
p ← 0
while x>1 do
if x is odd then Do Do
p ← p+y something something
x ← x/2
y ← 2y
else
x ← x/2 Is x>1?
y ← 2y
end while
p ← p + y Add up and
print p output product
Multiplication -
Russian Peasant Method
Russian_Peasant_1(x,y) Russian_Peasant_2(x,y)
p ← 0 p ← 0
while x>1 do while x>0 do
if x is odd then if x is odd then
p ← p+y p ← p+y
x ← x/2 x ← x/2
y ← 2y y ← 2y
else end while
x ← x/2 print p
y ← 2y
end while
p ← p + y
print p
Multiplication -
Russian Peasant Method
▪ Compute 13 × 7 = 91 Russian_Peasant_2(x,y)
p ← 0
iteration x y p while x>0 do
initialize 13 7 0 if x is odd then
p ← p+y
After 1st 6 14 0+7 = 7 x ← x/2
After 2nd 3 28 7 y ← 2y
After 3rd 1 56 7+28 = 35 end while
print p
After 4th 0 108 35+56 = 91
Russian Peasant Method –
Time Complexity
▪ Compute 13 × 7 = 91 Russian_Peasant_2(x,y)
p ← 0
iteration x y p while x>0 do
initialize 13 7 0 if x is odd then
p ← p+y
After 1st 6 14 0+7 = 7 x ← x/2
After 2nd 3 28 7 y ← 2y
After 3rd 1 56 7+28 = 35 end while
print p
After 4th 0 108 35+56 = 91

Running Time. Let 𝑛 be number of digits of 𝑥 and 𝑦, i.e. input size


is 𝑂 𝑛 . Then we have running time
𝑇 𝑛 = #iteration × time for each iteration
= #iteration × 𝑂 𝑛 = 𝑛 × 𝑂 𝑛 = 𝑂 𝑛2 .
Russian Peasant Method –
Proof of Correctness
▪ Compute 13 × 7 = 91 Russian_Peasant_2(x,y)
p ← 0
iteration x y p while x>0 do
initialize 13 7 0 if x is odd then
p ← p+y
After 1st 6 14 0+7 = 7 x ← x/2
After 2nd 3 28 7 y ← 2y
After 3rd 1 56 7+28 = 35 end while
print p
After 4th 0 108 35+56 = 91

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

𝑥0 × 𝑦0 + 𝑝0 = 𝑥 × 𝑦 After 1st 6 14 0+7 = 7


After 2nd 3 28 7

▪ Hypothesis: After 3rd 1 56 7+28 = 35


After 4th 0 108 35+56 = 91
(Show claim is true for some i=k-1)
Suppose that 𝑥𝑘−1 × 𝑦𝑘−1 + 𝑝𝑘−1 = 𝑥 × 𝑦 for some 𝑘
Russian Peasant Method –
Proof of Correctness Russian_Peasant_2(x,y)
p ← 0
while x>0 do
Claim: if x is odd then
p ← p+y
For every 𝑖-th iteration, 𝑥𝑖 × 𝑦𝑖 + 𝑝𝑖 = 𝑥 × 𝑦 x ← x/2
y ← 2y
▪ Induction Step: end while
(Show claim is true for i=k) print p

Case 1: 𝑥𝑘−1 is even. iteration x y p


initialize 13 7 0
𝑝𝑘 = 𝑝𝑘−1 After 1st 6 14 0+7 = 7
𝑥𝑘−1
Then ൞ 𝑥𝑘 = 2 After 2nd 3 28 7
After 3rd 1 56 7+28 = 35
𝑦𝑘 = 2𝑦𝑘−1
After 4th 0 108 35+56 = 91
𝑥
𝑥𝑘 × 𝑦𝑘 + 𝑝𝑘 = 𝑘−1 × 2𝑦𝑘−1 + 𝑝𝑘−1
2
= 𝑥𝑘−1 × 𝑦𝑘−1 + 𝑝𝑘−1 = 𝑥 × 𝑦
Russian Peasant Method –
Proof of Correctness Russian_Peasant_2(x,y)
p ← 0
while x>0 do
Claim: if x is odd then
p ← p+y
For every 𝑖-th iteration, 𝑥𝑖 × 𝑦𝑖 + 𝑝𝑖 = 𝑥 × 𝑦 x ← x/2
y ← 2y
▪ Induction Step: end while
(Show claim is true for k) print p

Case 2: 𝑥𝑘−1 is odd. iteration x y p


initialize 13 7 0
𝑝𝑘 = 𝑝𝑘−1 + 𝑦 After 1st 6 14 0+7 = 7
𝑥 −1
Then ൞ 𝑥𝑘 = 𝑘−1
2
After 2nd 3 28 7
After 3rd 1 56 7+28 = 35
𝑦𝑘 = 2𝑦𝑘−1 After 4th 0 108 35+56 = 91
𝑥 −1
𝑥𝑘 × 𝑦𝑘 + 𝑝𝑘 = 𝑘−1 × 2𝑦𝑘−1 + 𝑝𝑘−1 + 𝑦
2
= 𝑥𝑘−1 × 𝑦𝑘−1 + 𝑝𝑘−1 = 𝑥 × 𝑦

You might also like