Select the maximum number of non-overlapping activities from a set of candidates, each with a start and finish time — solved optimally with a greedy approach.
Algorithm & Complexity
| Operation | Time | Space |
|---|---|---|
| Sort by finish | O(n log n) | O(1) / O(n)* |
| Greedy scan | O(n) | O(1) |
| Total | O(n log n) | O(n) |
| * If pre-sorted input is given, the full algorithm runs in O(n). | ||
The greedy choice property holds: selecting the activity with the earliest finish time never rules out more activities than any other choice. Formally, if an optimal solution skips the earliest-finishing activity A, we can always swap whatever activity B it chose for A without reducing the solution size — since A finishes no later than B, it's at least as compatible with future activities.
Key Concepts
Activity Selection has both an optimal substructure and the greedy choice property. DP would work but is overkill — it runs in O(n²). The greedy approach is simpler, faster (O(n log n) due to sort), and provably optimal. DP is preferred for Weighted activity selection where each activity has a profit and we maximize total profit.
Correctness is proven via the exchange argument: suppose an optimal solution OPT doesn't include activity a₁ (earliest finish). Let b be OPT's first activity. Replace b with a₁ — since f(a₁) ≤ f(b), this new solution is also valid and has the same size. Repeating shows greedy = optimal.