CS2040S Data Structures and Algorithms: Welcome!
CS2040S Data Structures and Algorithms: Welcome!
Welcome!
is open
How to Search!
Algorithm Analysis
– Big-O Notation
– Model of computation
Searching
Peak Finding
– 1-dimension
– 2-dimensions
Admin: Tutorial/Recitations
For example:
• Total number of keys = 1024
• Number of correct keys = 17
Competition:
Find the keys!
Algorithm Analysis
– Big-O Notation
– Model of computation
Searching
Peak Finding
– 1-dimension
– 2-dimensions
Last time…
Binary Search
• Simple, ubiquitous algorithm.
• Surprisingly easy to add bugs.
• Some ideas for avoiding bugs:
• Problem specification
• Preconditions
• Postconditions
• Invariants / loop invariants
• Validate (when feasible)
Binary Search
Sorted array: A[0..n-1]
T2
T3
Tutorials
(in order T4
of tutor
preference)
T5
T6
T7
T8
A problem…
Tutorial allocation
T1 Students want
certain tutorials.
T2
T3
Tutorials
(in order T4
of tutor
preference)
T5
T6
T7
T8
A problem…
Tutorial allocation
T1 Students want
certain tutorials.
T2
T3 We want each
Tutorials tutorial to have
(in order T4
of tutor < 18 students..
preference)
T5
T6
T7
T8
A problem…
Tutorial allocation
T1 Students want
certain tutorials.
T2
T3 We want each
Tutorials tutorial to have
(in order T4
of tutor < 18 students..
preference)
T5
T8
A problem…
Tutorial allocation
T1 Students want
certain tutorials.
T2
T3 We want each
Tutorials tutorial to have
(in order T4
of tutor < 18 students..
preference)
T5
T8
A problem…
Tutorial allocation
T1 Can we do
greedy allocation?
T2
First, fill T1.
T3 Then fill T2.
Tutorials Then fill T3.
(in order T4 …
of tutor
preference) Stop when all
T5 students are
allocated
T6
T7
T8 or on Zoom.
A problem…
Tutorial allocation
T1 Can we do
greedy allocation?
T2
NO
T3
Tutorials Assume max
(in order T4 tutorial size is 1.
of tutor
preference)
T5 Assign student 1 to
tutorial 1.
T6
Now we need all 8
T7 tutorials.
T8
A problem…
Tutorial allocation
T1 Can we do
greedy allocation?
T2
NO
T3
Tutorials Assume max
(in order T4 tutorial size is 1.
of tutor
preference)
T5 Assign student 1 to
tutorial 1.
T6
Now one student
T7 has no feasible
allocation!
T8
A problem… Example of decomposing
an algorithm into parts!
Tutorial allocation
T1 Assume we can
solve allocation
T2 problem:
T6
T7
T8
A problem…
Tutorial allocation
T1 Observation:
T2 Number of
students in
T3 BIGGEST tutorial
Tutorials only decreases as
(in order T4 number of tutorials
of tutor
preference) increases.
T5
T6 Monotonic
function of
T7 number of
tutorials!
T8
A problem…
Tutorial allocation
T1
Monotonic
T2
function of
number of
T3
tutorials!
Tutorials
(in order T4
of tutor
preference)
T5
T6 Binary Search
T7
T8
A problem… T1
T2
Tutorial allocation T3
T4
Solution: T5
T6
Binary Search
T7
Define:
T8
T2
T3
T
4
crowded tutorial, T
6
if we offer x tutorials. T7
Search(n) T
8
begin = 0
end = n-1
while begin < end do:
mid = begin + (end-begin)/2;
if MaxStudents(mid) <= 18 then
end = mid
else begin = mid+1
return begin
Binary Search
Sorted array: A[0..n-1]
Algorithm Analysis
– Big-O Notation
– Model of computation
Searching
Peak Finding
– 1-dimension
– 2-dimensions
Peak Finding
Global
Maximum
Input: Some function f(x)
f(x)
x
local maximum
Peak Finding
Global Maximum for Optimization problems:
– Find a good solution to a problem.
– Find a design that uses less energy.
– Find a way to make more money.
– Find a good scenic viewpoint.
– Etc.
Why local maximum?
– Finds a good enough solution.
– Local maxima are close to the global maximum?
– Much, much faster.
Global Maximum
Input: Array A[0..n-1]
Output: global maximum element in A
How long to find a global maximum?
Input: Array A[0..n-1]
Output: maximum element in A
1. O(log n)
2. O(n)
3. O(n log n)
4. O(n2)
5. O(2n)
is open
Global Maximum
FindMax(A,n)
max = A[1]
for i = 1 to n do:
if (A[i]>max) then max=A[i]
Too slow!
Time Complexity: O(n)
Peak (Local Maximum) Finding
f(x)
x
Output: A local maximum
Peak Finding
Assume that
A[-1] = A[n] = -MAX_INT
Peak Finding: Algorithm 1
FindPeak
– Start from A[1]
– Examine every element
– Stop when you find a peak.
Peak Finding: Algorithm 1
FindPeak
– Start from A[1]
– Examine every element
– Stop when you find a peak.
Peak Finding: Algorithm 1
FindPeak
– Start from A[1]
– Examine every element
– Stop when you find a peak.
Peak Finding: Algorithm 1
Running time: n
Simple improvement?
Peak Finding: Algorithm 1
Worst-case: n/2
Peak Finding: Algorithm 2
Reduce-and-Conquer
We found a peak!
Peak Finding
FindPeak(A, n)
if A[n/2] is a peak then return n/2
else if A[n/2+1] > A[n/2] then
Search for peak in right half.
else if A[n/2–1] > A[n/2] then
Search for peak in left half.
Peak Finding
FindPeak(A, n)
if A[n/2] is a peak then return n/2
else if A[n/2+1] > A[n/2] then
FindPeak (A[n/2+1..n], n/2)
else if A[n/2–1] > A[n/2] then
FindPeak (A[1..n/2-1], n/2)
Peak Finding
Is this correct? is open
FindPeak(A, n)
if A[n/2] is a peak then return n/2
else if A[n/2+1] > A[n/2] then
FindPeak (A[n/2+1..n], n/2)
else if A[n/2–1] > A[n/2] then
FindPeak (A[1..n/2-1], n/2)
Peak Finding
Missing else condition? No: else we have found a peak!
FindPeak(A, n)
if A[n/2] is a peak then return n/2
else if A[n/2+1] > A[n/2] then
FindPeak (A[n/2+1..n], n/2)
else if A[n/2–1] > A[n/2] then
FindPeak (A[1..n/2-1], n/2)
Peak Finding
Missing else condition? No: else we have found a peak!
FindPeak(A, n)
if A[n/2+1] > A[n/2] then
FindPeak (A[n/2+1..n], n/2)
else if A[n/2–1] > A[n/2] then
FindPeak (A[1..n/2-1], n/2)
else A[n/2] is a peak; return n/2
Peak Finding
Key property è invariant:
If we recurse in the right half, then there exists a peak
in the right half.
Peak Finding
Key property:
– If we recurse in the right half, then there exists a
peak in the right half.
Explanation:
– Assume there is “no peak” in the right half.
– Given: A[middle] < A[middle + 1]
– Since no peaks, A[middle+1] < A[middle+2]
– Since no peaks, A[middle+2] < A[middle+3]
– …
– Since no peaks, A[n-1] < A[n] PEAK!!
Peak Finding
Recurse on right half, since 23 > 6.
Assume no peaks in right half.
Peak Finding
Key property:
– If we recurse in the right half, then there exists a
peak in the right half.
Explanation:
– Assume there is “no peak” in the right half.
– Because we recursed right: A[middle] < A[middle + 1]
– Since no peaks, A[middle+1] < A[middle+2]
– Since no peaks, A[middle+2] < A[middle+3]
– …
– Since no peaks, A[n-1] < A[n] PEAK!!
Peak Finding
Key property:
– If we recurse in the right half, then there exists a
peak in the right half.
Induction:
– Assume there is “no peak” in the right half.
– Inductive hypothesis:
For all (j > middle): A[j-1] < j
Peak Finding
Key property:
– If we recurse in the right half, then there exists a
peak in the right half.
Induction:
– Assume there is “no peak” in the right half.
– Inductive hypothesis:
For all (j > middle): A[j-1] < j
– Base case: j = middle+1
Because we recursed on the right half, we know that
A[middle] < A[middle + 1].
Peak Finding
Key property:
– If we recurse in the right half, then there exists a
peak in the right half.
Induction:
– Assume there is “no peak” in the right half.
– Inductive hypothesis:
For all (j > middle): A[j-1] < j
– Induction: j > middle+1
By induction, A[j-2] <= A[j-1].
If A[j-1] >= A[j], then A[j-1] is a peak è contradiction.
Peak Finding
Key property:
– If we recurse in the right half, then there exists a
peak in the right half.
Induction:
– Assume there is “no peak” in the right half.
– Inductive hypothesis:
For all (j > middle): A[j-1] < j
– Conclusion: A[n-2] < A[n-1]
è A[n-1] is a peak è contradiction.
Key Invariants:
Correctness:
begin end
Key Invariants:
Is this good enough to prove the algorithm works?
begin end
is open
Key Invariants:
Not good enough to prove the algorithm works!
begin end
Key Invariants:
Not good enough to prove the algorithm works!
begin end
Key Invariants:
Not good enough to prove the algorithm works!
Non-border peak
Peak Finding
Key property:
– If we recurse in the right half, then every peak in
the right half is a peak in the array.
Proof: use the invariant (inductively)
– True by invariant for current array.
Recurse here
Running time?
FindPeak(A, n)
if A[n/2] is a peak then return n/2
else if A[n/2+1] > A[n/2] then
Search for peak in right half.
else if A[n/2–1] > A[n/2] then
Search for peak in left half.
Peak Finding
Running time: Time for comparing
A[n/2] with neighbors
Time to find a peak in
an array of size n Recursion
2 x 2 x…x 2 = 2log(n) = n
log(n)
log(n)
Peak Finding
Assume that
A[-1] = A[n] = -MAX_INT
Steep Peaks
Assume that
A[-1] = A[n] = -MAX_INT
Steep Peaks
is open