Input: A list of intervals, each with a:
• Start time si
• Finish time fi
Output: A subset of non-overlapping
intervals
Goal: The largest possible subset
Input: A list of intervals, each with a:
• Start time si
• Finish time fi
Output: A subset of non-overlapping
intervals
Goal: The largest possible subset
Naïve algorithm: Try every possible subset
Practical Example
Input: A list of classes, with their start and finish
time
Output: A sub-list of the classes to be assigned
to the same classroom
Goal: Assign as many classes as possible to the
classroom.
Sample Problem
Optimal Solution
2nd Optimal Solution
Process randomly
Decision: Use the class if you can.
Clearly: Not a correct algorithm
Process by longest
Process by earliest start time
Process by shortest length
Process by (earliest) finish time
IntervalScheduling(Vector classes)
(1)sort(classes)
// Sort by finish time
(2)Vector Results = ()
(3)bound -
(4)for i 0 to n-1
(5)
if classes[i].start ≥ bound
(6)
Results.push(i)
(7)
bound = classes[i].finish
Input:
Class: C= {c1, c2, …, cn}
Start time: s(ci)
Finish time: f(ci)
Assume class list has already been sorted:
if i < j than f(ci) ≤ f(cj)
Output:
O = {o1, o2, …, ok}
Means our solution is:
{co1, co2, …, cok}
Notice that if a < b:
oa < ob
f(coa) < s(cob)
Let’s call these f(oa) and
s(ob) to make life easier
Consider input C:
• The algorithm spits out output O={o1, …, ok}
• There must be some optimal solution
B={b1, …, bh}
• If O=B, then we are good
• What if O≠B?
– Doesn’t matter – so long as k=h.
– We are going to turn B into O without changing the
number of elements h
• We will conclude that k=h – so O is also optimal
O = {o1, o2, o3, o4, …, ok}
B = {b1, b2, b3, b4, …, …,
bh}
?
If k=h, then O is (also) optimal
If k < h, then O is not optimal
O = {o1, o2, o3, o4, …, ok}
B = {b1, b2, b3, b4, …, …, bh}
If O≠B than they must be different somewhere.
Formally: i such that oi≠bi
So than there must be a smallest i where oi≠bi
O = {o1, o2, o3, o4, …, ok}
B = {o1, o2, b3, b4, …, …, bh}
If O≠B than they must be different somewhere.
Formally: i such that oi≠bi
So than there must be a smallest i where oi≠bi
O = {o1, o2, o3, o4, …, ok}
B = {o1, o2, b3, b4, …, …, bh}
I would like to change B by replacing bi with oi.
Will B still be a legal solution?
f(bi-1) ≤ s(oi)?
Yes: f(bi-1) = f(oi-1) ≤ s(oi)
O = {o1, o2, o3, o4, …, ok}
B = {o1, o2, b3, b4, …, …, bh}
I would like to change B by replacing bi with oi.
Will B still be a legal solution?
f(oi) ≤ s(bi+1)?
Yes: f(oi) ≤ f(bi) ≤ s(bi+1)
Crucial step – if f(oi) > f(bi), than the algorithm
would have picked class bi instead of class oi
Proof: Step 3
O = {o1, o2, o3, o4, …, ok}
B = {o1, o2, o3, b4, …, …, bh}
B is now “more like”O, but is still optimal.
So we can do this again, with a new “first difference”
And again…
And again…
After (at most) h substitutions:
How did we
jump to this?
B = {o1, …, ok, bk+1, …, bh }
Which means: h = k, or O is optimal.
Our algorithm is an example of a greedy algorithm
The runtime analysis is usually easy
The correctness proof can be difficult
© Copyright 2026 Paperzz