Welcome to COMP 157!

1.
A problem is divided into several (often 2)
sub-problems of same type, ideally of about
equal size.
2.
The sub-problems are solved (often
recursively).
3.
Combine solutions to sub-problems into
solution to overall problem.
ο‚‘
Summing n numbers:
π‘Ž0 + π‘Ž1 + π‘Ž2 + β‹― + π‘Žπ‘›βˆ’3 + π‘Žπ‘›βˆ’2 + π‘Žπ‘›βˆ’1
ο‚§ Recursively sum the two halves:
π‘Ž0 + π‘Ž1 + β‹― + π‘Ž 𝑛 + π‘Ž 𝑛 + β‹― + π‘Žπ‘›βˆ’2 + π‘Žπ‘›βˆ’1
2
2
β–ͺ And those two halves:
π‘Ž0 + … + π‘Ž 𝑛 + π‘Ž 𝑛 + β‹― + π‘Ž 𝑛
4
+
4
2
π‘Ž 𝑛 + β‹― + π‘Ž 3𝑛 + π‘Ž 3𝑛 + β‹― + π‘Žπ‘›βˆ’1
2
4
4
ο‚‘
Summing n numbers:
π‘Ž0 + π‘Ž1 + π‘Ž2 + β‹― + π‘Žπ‘›βˆ’3 + π‘Žπ‘›βˆ’2 + π‘Žπ‘›βˆ’1
ο‚§ Recursively sum the two halves:
β–ͺ … Down to single numbers:
ο‚‘
This case: no more efficient than Brute Force.
ο‚§ Many divide and conquer algs very efficient
ο‚§ Well suited to parallel implementation.
ο‚‘
Assuming instance of size n is divided into b
sub-problems, each sized n/b with a of them
needing to be solved to solve the whole
problem:
𝑛
𝑇 𝑛 =π‘Žβˆ™π‘‡
+𝑓 𝑛
𝑏
ο‚§ Where f(n) is computation to divide up then
recombine sub-problems.
ο‚‘
Master Theorem: if 𝑓 𝑛 ∈ πœƒ 𝑛𝑑 where d β‰₯ 0
then:
πœƒ 𝑛𝑑
𝑖𝑓 π‘Ž < 𝑏 𝑑
𝑇 𝑛 ∈
πœƒ 𝑛𝑑 βˆ™ log 𝑛
𝑖𝑓 π‘Ž = 𝑏 𝑑
πœƒ 𝑛log𝑏 π‘Ž
𝑖𝑓 π‘Ž > 𝑏 𝑑
ο‚§ What would this imply for number of additions in
earlier example?
ο‚§ How about binary search?
ο‚‘
Assuming instance of size n is divided into b
sub-problems, each sized n/b with a of them
needing to be solved to solve the whole
problem:
𝑛
𝑇 𝑛 =π‘Žβˆ™π‘‡
+𝑓 𝑛
𝑏
ο‚§ If a = 1, then this covers decrease-by-a-constant-
factor algorithms.
β–ͺ Better to consider Decrease-and-Conquer as separate
approach.
ο‚‘
Recursively divide
array in half.
ο‚§ Stop at single element.
ο‚‘
Merge sorted halves
back into sorted array.
Mergesort(A[0…n-1])
Merge(B[0…p-1],C[0…q-1],A[0…n-1])
if n > 1
i ← 0; j ← 0; k ← 0;
copy A[0…n/2-1] to B[0…n/2-1]
while i < p and j < q do
copy A[n/2…n-1] to C[0…n/2-1]
if B[i] ≀ C[j]
Mergesort(B[0…n/2-1])
A[k] ← B[i];
Mergesort(C[0…n/2-1])
i ← i+1;
Merge(B,C,A)
else
A[k] ← B[j];
j ← j+1;
k ← k+1;
if i = p
copy C[j…q-1] to A[k…n-1]
else
copy B[i…p-1] to A[k…n-1]
8
3
2
9
7
1
5
4
ο‚‘
Assuming that n is a power of 2:
𝑛
𝐢 𝑛 =2βˆ™πΆ
+ πΆπ‘šπ‘’π‘Ÿπ‘”π‘’ 𝑛 π‘“π‘œπ‘Ÿ 𝑛 > 1
2
𝐢 1 =0
πΆπ‘šπ‘’π‘Ÿπ‘”π‘’ 𝑛 = 𝑛 βˆ’ 1
ο‚‘
According to Master Theorem, what is Θ(g(n))
for mergesort?
Stable
 Requires linear amount of extra space

ο‚‘
Variation: multiway mergesort divides into
more than 2 sub-arrays.
ο‚§ Often used in file sorting.
LomutoPartition(A[l…r])
p ← A[l]
s ← l
for i ← l + 1 to r do
if A[i] < p
s ← s + 1
swap(A[s], A[i])
swap(A[l], A[s])
return s
ο‚‘
Partition the following array:
5
l,s
3
i
1
9
8
2
4
7
5
r
ο‚‘
Scan from both ends at once:
ο‚§ i starts at index 1 and moves right until finds value
β‰₯ p.
ο‚§ j starts at index n-1 and moves left until finds
value ≀ p
β–ͺ Stopping when equal allows for more even split when
array has many duplicates.
ο‚‘
When scan stops, one of 3 situations exists:
1. i < j: we simply swap A[i] with A[j] and continue
scanning.
ο‚‘
When scan stops, one of 3 situations exists:
2. i > j: since scanning indices have crossed, the
array is partitioned and we simply need to swap
pivot with A[j] to put pivot into correct position.
ο‚‘
When scan stops, one of 3 situations exists:
3. i = j: must both be pointing to value that is same
as pivot, so array is fully partitioned with no
swaps.
β–ͺ
Can merge with case 2 because swapping pivot with
A[j] doesn’t change array at all.
HoarePartition(A[l…r])
p ← A[l]
i ← l; j ← r+1
repeat
repeat
i ← i+1
until A[i] β‰₯ p
repeat
j ← j-1
until A[j] ≀ p
swap(A[i],A[j])
until i β‰₯ j
swap(A[i], A[j]) // undo last swap when i β‰₯ j
swap(A[l], A[j])
return j
ο‚‘
Partition the following array using Hoare
Partitioning:
5
3
1
9
8
2
4
7
l
ο‚‘
8
l
r
Your turn:
1
10
16
7
12
9
2
15
r
ο‚‘
Recursively applies partitioning until array is
fully sorted.
Quicksort(A[l…r])
if l < r
s ← Partition(A[l…r]) // s is split position
Quicksort(A[l…s-1])
Quicksort(A[s+1…r])
ο‚§
ο‚§
ο‚§
Best case: Θ(n log n)
Worst case: O(n2)
Avg case: ~1.39 n log2n
ο‚§ Usually faster than Mergesort, can improve 30%:
ο‚§ Better pivot selection algorithms: e.g. median of three
ο‚§ 3-way partition
ο‚§ Insertion sort for small subarrays (5-15 elements)
Requires logarithmic extra space
 Not stable.

Convex hull: smallest convex set that includes
given points
ο‚‘ Sort points by x-coordinate values
ο‚‘ Identify extreme points P1 and P2 (leftmost
and rightmost)
ο‚§ Splits points into 2 sets S1 and S2.
P2
P1
ο‚‘
Compute upper (and lower) hull recursively:
ο‚§ find point Pmax that is farthest away from line P1P2
ο‚§ compute the upper hull of the points outside line
P1Pmax
ο‚§ compute the upper hull of the points outside line
PmaxP2
Pmax
P1
P2
Discard points inside
P1 - P2- Pmax triangle.
ο‚§ compute the upper hull of the points outside line
P1Pmax
ο‚§ compute the upper hull of the points outside line
PmaxP2 (no points in set)
Pmax
P1
P2
ο‚‘
Sorting points in O(n log n) time
ο‚‘
Finding point farthest away from line P1P2 can
be done in linear time using determinant.
ο‚‘
Overall Time efficiency:
ο‚§ worst case: Θ(n2) (as quicksort)
ο‚§ average case: Θ(n) (under reasonable assumptions about
distribution of points given)
ο‚‘
Assume that your n points are sorted by xcoordinate in one list and by y-coordinate in
second list.
ο‚§ If not already, can sort in Θ(n log2n)
ο‚‘
If 2 ≀ n ≀ 3, use brute force.
ο‚‘
ο‚‘
If n > 3, draw line through
median of x-values and divide
points into 2 subsets, PL & PR
Apply recursively to PL & PR.
ο‚§ d = min(dL,dR)
ο‚§ Check pairs
within distance d
of median.
ο‚‘
d = min(dL,dR)
ο‚§ For points within distance d in x-
direction of median…
ο‚§ …check adjacent pairs in ysorted list within distance d
of each other…
ο‚§ …update d if necessary
ο‚§ At most 6 such points
ο‚‘
ο‚‘
ο‚‘
Dividing Problem in halves: linear time
Combining Solutions: linear time
𝑛
𝑇 𝑛 = 2𝑇
+ 𝑓 𝑛1
2
Applying Master Theorem: Θ(n log2n)
ο‚§ Has been proven that not possible to solve closest
pair in fewer than Θ(n log2n) operations.