Activity Selection Problem in DSA Java - Time & Space Complexity
We want to understand how the time needed to pick activities grows as the number of activities increases.
How does the program's work change when we have more activities to choose from?
Analyze the time complexity of the following code snippet.
// Assumes activities sorted by finish time
int selectActivities(int[] start, int[] finish) {
int count = 1; // first activity always selected
int lastFinish = finish[0];
for (int i = 1; i < finish.length; i++) {
if (start[i] >= lastFinish) {
count++;
lastFinish = finish[i];
}
}
return count;
}
This code picks the maximum number of activities that don't overlap by checking each activity once.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: A single loop that goes through all activities once.
- How many times: Exactly once for each activity after the first.
As the number of activities grows, the code checks each one once to decide if it fits.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 9 checks |
| 100 | About 99 checks |
| 1000 | About 999 checks |
Pattern observation: The work grows directly with the number of activities.
Time Complexity: O(n)
This means the time to select activities grows in a straight line with the number of activities.
[X] Wrong: "The code checks every pair of activities, so it must be O(n²)."
[OK] Correct: The code only looks at each activity once in order, not comparing all pairs.
Understanding this linear time solution shows you can find efficient answers by smart ordering and simple loops, a key skill in many problems.
"What if the activities were not sorted by finish time? How would the time complexity change?"
Practice
Activity Selection Problem?Solution
Step 1: Understand the problem objective
The Activity Selection Problem aims to choose the largest set of activities that do not overlap in time.Step 2: Identify the correct goal
Among the options, only selecting the maximum number of non-overlapping activities matches the problem's goal.Final Answer:
Select the maximum number of activities that don't overlap -> Option DQuick Check:
Goal = Max non-overlapping activities [OK]
- Confusing longest duration with maximum count
- Sorting by start time only
- Summing all activity durations
Solution
Step 1: Identify sorting criteria for Activity Selection
Activities must be sorted by their finish time in ascending order to apply the greedy approach.Step 2: Match code to sorting by finish time ascending
Arrays.sort(activities, (a, b) -> a.finish - b.finish); sorts by finish time ascending (a.finish - b.finish), which is correct.Final Answer:
Arrays.sort(activities, (a, b) -> a.finish - b.finish); -> Option AQuick Check:
Sort by finish time ascending = Arrays.sort(activities, (a, b) -> a.finish - b.finish); [OK]
- Sorting by start time instead of finish time
- Sorting in descending order
- Using incorrect comparator syntax
class Activity {
int start, finish;
Activity(int s, int f) { start = s; finish = f; }
}
Activity[] activities = {
new Activity(1, 4),
new Activity(3, 5),
new Activity(0, 6),
new Activity(5, 7),
new Activity(8, 9),
new Activity(5, 9)
};
Arrays.sort(activities, (a, b) -> a.finish - b.finish);
int count = 1;
int lastFinish = activities[0].finish;
for (int i = 1; i < activities.length; i++) {
if (activities[i].start >= lastFinish) {
count++;
lastFinish = activities[i].finish;
}
}
System.out.println(count);Solution
Step 1: Sort activities by finish time ascending
The activities in sorted order (stable sort preserves order of ties): (1,4), (3,5), (0,6), (5,7), (8,9), (5,9)Step 2: Trace the greedy selection
Pick (1,4), count=1, lastFinish=4
Skip (3,5) since 3 < 4
Skip (0,6) since 0 < 4
Pick (5,7) since 5 >= 4, count=2, lastFinish=7
Pick (8,9) since 8 >= 7, count=3, lastFinish=9
Skip (5,9) since 5 < 9Step 3: Check if any other activities can be selected
All activities considered, total count = 4 (including the first selected activity)Final Answer:
4 -> Option CQuick Check:
Greedy selection count = 4 [OK]
- Not sorting activities before selection
- Selecting overlapping activities
- Incorrectly updating last finish time
Arrays.sort(activities, (a, b) -> a.finish + b.finish);
int count = 1;
int lastFinish = activities[0].finish;
for (int i = 1; i < activities.length; i++) {
if (activities[i].start >= lastFinish) {
count++;
lastFinish = activities[i].finish;
}
}
System.out.println(count);Solution
Step 1: Analyze the comparator in Arrays.sort
The comparator uses a.finish + b.finish, which does not correctly compare finish times. It should use subtraction (a.finish - b.finish) to sort ascending.Step 2: Understand impact of incorrect comparator
Using addition returns a positive number regardless of order, causing incorrect sorting and wrong activity selection.Final Answer:
Comparator uses addition instead of subtraction for sorting -> Option BQuick Check:
Comparator must subtract finish times [OK]
- Using addition in comparator instead of subtraction
- Starting loop at wrong index
- Misunderstanding condition operator
int[] start = {1, 3, 0, 5, 8, 5};
int[] finish = {2, 4, 6, 7, 9, 9};Which set of activities selected by the greedy algorithm (selecting earliest finish time first) is correct?
Solution
Step 1: Sort activities by finish time ascending
Activities sorted by finish time:
(1,2), (3,4), (0,6), (5,7), (8,9), (5,9)Step 2: Select activities greedily
Pick (1,2) first.
Next, (3,4) start=3 >=2 select.
(0,6) start=0 <4 skip.
(5,7) start=5 >=4 select.
(8,9) start=8 >=7 select.
(5,9) start=5 <7 skip.Step 3: Final selected set
[Activity(1,2), Activity(3,4), Activity(5,7), Activity(8,9)]Final Answer:
[Activity(1,2), Activity(3,4), Activity(5,7), Activity(8,9)] -> Option AQuick Check:
Greedy selection = [Activity(1,2), Activity(3,4), Activity(5,7), Activity(8,9)] [OK]
- Choosing activities with longer duration
- Selecting overlapping activities
- Ignoring sorting by finish time
Ready to prove it?
Pass the test and this pattern moves unknown
