Activity Selection Problem in DSA C - Time & Space Complexity
We want to understand how the time needed to select 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.
// Activities sorted by finish time
int selectActivities(int start[], int finish[], int n) {
int count = 1; // first activity always selected
int last = 0;
for (int i = 1; i < n; i++) {
if (start[i] >= finish[last]) {
count++;
last = i;
}
}
return count;
}
This code picks the maximum number of activities that don't overlap, assuming activities are sorted by finish time.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: A single loop that checks each activity once.
- How many times: The loop runs (n - 1) times, where n is the number of activities.
As the number of activities grows, the program checks each one once in order.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 9 checks |
| 100 | About 99 checks |
| 1000 | About 999 checks |
Pattern observation: The number of operations grows roughly in a straight line with the number of activities.
Time Complexity: O(n)
This means the time needed grows directly 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 loops once through the list, comparing each activity to the last selected one, not all pairs.
Understanding this helps you explain how greedy choices can lead to efficient solutions, a key skill in problem solving.
"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 goal
The Activity Selection Problem aims to choose the largest set of activities that do not overlap in their time intervals.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 in time -> Option CQuick Check:
Goal = Max non-overlapping activities [OK]
- Confusing longest duration with maximum count
- Sorting by start time only
- Trying to sum all activity times
Solution
Step 1: Identify sorting criteria
For the Activity Selection Problem, activities must be sorted by their finish time to select the maximum number of non-overlapping activities.Step 2: Match sorting function
OnlyqsortwithcompareFinishsorts by finish time correctly.Final Answer:
qsort(activities, n, sizeof(Activity), compareFinish); -> Option BQuick Check:
Sort by finish time = qsort + compareFinish [OK]
- Sorting by start time instead of finish time
- Using undefined compare functions
- Using wrong sorting function name
typedef struct {
int start;
int finish;
} Activity;
Activity activities[] = {{1, 4}, {3, 5}, {0, 6}, {5, 7}, {8, 9}, {5, 9}};
int n = 6;
// Assume activities are sorted by finish time
int count = 1;
int last_finish = activities[0].finish;
for (int i = 1; i < n; i++) {
if (activities[i].start >= last_finish) {
count++;
last_finish = activities[i].finish;
}
}
printf("%d\n", count);Solution
Step 1: Trace the selection process
Activities sorted by finish time: (1,4), (3,5), (0,6), (5,7), (8,9), (5,9). Start with count=1, last_finish=4.
Check each activity:
- (3,5): start 3 < 4, skip
- (0,6): start 0 < 4, skip
- (5,7): start 5 >= 4, select, count=2, last_finish=7
- (8,9): start 8 >= 7, select, count=3, last_finish=9
- (5,9): start 5 < 9, skipStep 2: Final count of selected activities
Total selected activities = 4Final Answer:
4 -> Option DQuick Check:
Selected count = 4 [OK]
- Not sorting activities by finish time
- Selecting overlapping activities
- Incorrectly updating last_finish
typedef struct {
int start;
int finish;
} Activity;
Activity activities[] = {{1, 3}, {2, 5}, {4, 7}};
int n = 3;
// Activities are sorted by finish time
int count = 0;
int last_finish = 0;
for (int i = 0; i < n; i++) {
if (activities[i].start > last_finish) {
count++;
last_finish = activities[i].finish;
}
}
printf("%d\n", count);Solution
Step 1: Analyze the selection condition
The condition uses '>' which excludes activities starting exactly at last_finish time. It should allow activities starting at or after last_finish, so '>=' is correct.Step 2: Check other parts
Starting loop at 0 and initializing last_finish to 0 is fine if condition is corrected. The activities are sorted as stated.Final Answer:
The condition should be activities[i].start >= last_finish -> Option AQuick Check:
Use >= to include activities starting at last finish [OK]
- Using > excludes valid activities
- Starting loop from 1 unnecessarily
- Wrong initialization of last_finish
Activities = [(1, 2), (3, 4), (0, 6), (5, 7), (8, 9), (5, 9)]
Which set of activities represents the maximum number of non-overlapping activities selected by the greedy algorithm?
Solution
Step 1: Sort activities by finish time
Sorted activities: (1,2), (3,4), (0,6), (5,7), (8,9), (5,9)Step 2: Select activities greedily
Select (1,2) first.
Next, (3,4) starts after 2, select.
(0,6) overlaps, skip.
(5,7) starts after 4, select.
(8,9) starts after 7, select.
(5,9) overlaps, skip.
Selected set: [(1,2), (3,4), (5,7), (8,9)]Final Answer:
[(1, 2), (3, 4), (5, 7), (8, 9)] -> Option AQuick Check:
Greedy selects max non-overlapping activities [OK]
- Choosing overlapping activities
- Not sorting by finish time
- Selecting longer activities first
Ready to prove it?
Pass the test and this pattern moves unknown
