Choose the interval with the smallest right endpoint, stab at this right endpoint, eliminate the intervals that have been stabbed, and recurse.
(picture)
Let \(g_1, g_2,\ldots,g_m\) be the stabs made by the greedy algorithm (in order from left to right), and suppose \(g_1,g_2,\ldots, g_{j-1}, c_j, c_{j+1},\ldots, c_{m'}\) is another set of stabs (in order) that stab all the intervals, with \(m' \leq m\).
\(c_j\) must stab the interval \(I\) with the leftmost right endpoint, after eliminating those stabbed by \(g_1,g_2,\ldots, g_{j-1}\).
Moving \(c_j\) to \(g_j\) (the right endpoint of \(I\)) stabs all of the same intervals, because no other intervals end before interval \(I\) does.
In this way, all of the \(c_i\)’s can be replaced with \(g_i\)’s, so \(m = m'\).
Algorithm(L[1..n], R[1..n])
if n = 0 //empty list
return 0
else
min = infinity
for i <- 1 to n
if R[i] < min
min = R[i] //finding stabpoint
newL = L[1..n]
newR = R[1..n]
for j <- 1 to n
if min >= L[j] && min <= R[j] //finding if stabpoint overlaps with each brick
newL[] <- newL \ L[j] //takes away that brick from array
newR[] <- newR \ R[j]
return 1 + Algorithm(newL[], newR[])
Time: \(O(n^2)\) (linear work inside tail recursion)
Stabby(R[1..n], L[1..n]):
counter <- 0
MergeSort R and permute L to match
i <- 1
while i <= n
stab <- R[i]
counter++
while L[i] <= stab \\ then it got stabbed
i++ \\ keep checking and skipping what gets stabbed
return counter
Time: \(O(n \log n)\), because the loop runs in \(O(n)\) time, incrementing \(i\) until it exceeds \(n\).
Note: The second while loop won’t remove intervals that have later end times than some unstabbed interval. But these will get removed eventually; at the very latest, at the last stab. Such an interval would never have the leftmost right endpoint, and so would never determine the location of a stab. So it won’t affect the greedy choices, or the final value of counter
.
Example:
character | A | E | I | O | U | Y |
code word | 000 | 001 | 010 | 011 | 100 | 101 |
Example:
character | A | E | I | O | U | Y |
code word | 00 | 01 | 10 | 11 | 100 | 101 |
10110010
.Table #1 | Table #2 | Table #3 | Table #4 | Table #5 | Table #6 | Table #7 |
---|---|---|---|---|---|---|
Claire | Grace | Andrew | Logan | Trevor | Drake | Levi |
Blake | Kristen | James | John | Ethan | Bri | Talia |
Josiah | Jack | Kevin | Graham | Jordan | Nathan | Isaac |
Example:
character | A | E | I | O | U | Y |
code word | 10 | 111 | 001 | 000 | 110 | 01 |
Now there’s only one way to decode anything: \[ \mathtt{101100110} \mapsto \mathtt{AUYA} \]
character | A | E | I | O | U | Y |
code word | 10 | 111 | 001 | 000 | 110 | 01 |
#
0/ \1
# #
0/ \1 0/ \1
# Y A #
0/ \1 0/ \1
O I U E
Suppose we want to encode the following message:
YOEAEEIAAOEOEEAIAYAOAAYYYAUEEAOEEEEUAEOAEUAAYAIAEIEEEEOEIEEIEIAYAEOUEEEUYYAEAEOUAYIYUEUIEOEIEUAIOEEEAEIEEOIEEEOAUEEUEIEOEUEEAAYAEOYAAEIYEEUEAOAEEOIAIEAAIIUIEUEAUIEEEAUUIAEEEOOIEAAYEIEAAAEOOOAUAYIOIEAEOYUIAEYAEEOAAAIEEYIOYEOEEOOOIE
This message contains 80 Es, 50As, 30 Os, 30Is, 20Us, and 20Ys.
character | A | E | I | O | U | Y |
frequency | 50 | 80 | 30 | 30 | 20 | 20 |
We want to construct a prefix code that uses the fewest number of bits for the whole message.
The message contains 80 Es, 50As, 30 Os, 30Is, 20Us, and 20Ys.
character | A | E | I | O | U | Y |
frequency | 50 | 80 | 30 | 30 | 20 | 20 |
Encode it using the following prefix code:
character | A | E | I | O | U | Y |
code word | 10 | 111 | 001 | 000 | 110 | 01 |
This requires 50*2 + 80*3 + 30*3 + 30*3 + 20*3 + 20*2
= 620 bits.
Given: A list of characters C[1..n]
and their frequencies F[1..n]
in the message we want to encode.
Goal: Construct a binary tree for a prefix code that uses the fewest number of bits to encode the message.
Algorithm: Start with a “forest” of leaves: every character is a leaf.
character | A | E | I | O | U | Y |
frequency | 50 | 80 | 30 | 30 | 20 | 20 |
Start with a “forest” of leaves: every character is a leaf:
A:50 E:80 I:30 O:30 U:20 Y:20
Find the two trees in this forest with smallest total frequency. Join these two trees under a common root:
A:50 E:80 I:30 O:30 #:40
/ \
U Y
Recurse:
A:50 E:80 #:60 #:40
/ \ / \
I O U Y
character | A | E | I | O | U | Y |
frequency | 50 | 80 | 30 | 30 | 20 | 20 |
A:50 E:80 #:60 #:40
/ \ / \
I O U Y
Recurse:
E:80 #:60 #:90
/ \ / \
I O A #
/ \
U Y
Recurse:
#:140 #:90
/ \ / \
E # A #
/ \ / \
I O U Y
#:140 #:90
/ \ / \
E # A #
/ \ / \
I O U Y
One final recursion:
#
/ \
# #
/ \ / \
E # A #
/ \ / \
I O U Y
Optimal code?
character | A | E | I | O | U | Y |
code word | 10 | 00 | 010 | 011 | 110 | 111 |
character | A | E | I | O | U | Y |
frequency | 50 | 100 | 30 | 30 | 20 | 20 |
character | A | E | I | O | U | Y |
frequency | | | | | | |