Activity Selection Problem in DSA Javascript - 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.
function activitySelection(start, finish) {
let n = start.length;
let selected = [0];
let last = 0;
for (let i = 1; i < n; i++) {
if (start[i] >= finish[last]) {
selected.push(i);
last = i;
}
}
return selected;
}
This code selects 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 once for each activity after the first, so n-1 times.
As the number of activities grows, the program 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 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 in proportion to the number of activities.
[X] Wrong: "The loop runs multiple times for each activity because of nested checks."
[OK] Correct: The code only has one simple loop that goes through activities once, so it does not multiply work inside the loop.
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: Clarify what is NOT the goal
Finding the longest activity or sorting alone does not solve the problem; the focus is on maximizing non-overlapping activities.Final Answer:
Select the maximum number of activities that don't overlap in time -> Option AQuick Check:
Maximize non-overlapping activities = Select max activities [OK]
- Thinking it's about longest activity duration
- Confusing sorting with selection
- Trying to maximize total time instead of count
Solution
Step 1: Identify sorting key for Activity Selection
We must sort activities by their finish time in ascending order to apply the greedy approach.Step 2: Choose correct JavaScript sort syntax
The correct syntax isactivities.sort((a, b) => a.finish - b.finish);which sorts by finish time ascending.Final Answer:
activities.sort((a, b) => a.finish - b.finish); -> Option AQuick Check:
Sort by finish time ascending = activities.sort((a, b) => a.finish - b.finish); [OK]
- Sorting by start time instead of finish time
- Sorting finish time descending
- Sorting by duration which is irrelevant here
const activities = [
{start: 1, finish: 4},
{start: 3, finish: 5},
{start: 0, finish: 6},
{start: 5, finish: 7},
{start: 8, finish: 9},
{start: 5, finish: 9}
];
activities.sort((a, b) => a.finish - b.finish);
let count = 1;
let lastFinish = activities[0].finish;
for (let i = 1; i < activities.length; i++) {
if (activities[i].start >= lastFinish) {
count++;
lastFinish = activities[i].finish;
}
}
console.log(count);Solution
Step 1: Sort activities by finish time
Sorted activities by finish time ascending: [{start:1, finish:4}, {start:3, finish:5}, {start:0, finish:6}, {start:5, finish:7}, {start:8, finish:9}, {start:5, finish:9}].Step 2: Select activities greedily
Start with first activity (finish=4). Next, select activities starting >=4: (start=5, finish=7), count=2; then (start=8, finish=9), count=3; then (start=9, finish=9) does not exist but next is (start=5, finish=9) which starts before 9, so skip. Total count is 4.Final Answer:
4 -> Option DQuick Check:
Greedy selection count = 4 [OK]
- Not sorting activities before selection
- Counting overlapping activities
- Updating lastFinish incorrectly
function selectActivities(activities) {
activities.sort((a, b) => a.start - b.start);
let count = 1;
let lastFinish = activities[0].finish;
for (let i = 1; i < activities.length; i++) {
if (activities[i].start > lastFinish) {
count++;
lastFinish = activities[i].finish;
}
}
return count;
}Solution
Step 1: Check sorting criteria
The greedy approach requires sorting activities by their finish time, but the code sorts by start time, which is incorrect.Step 2: Understand impact of wrong sorting
Sorting by start time can cause wrong selection order, leading to suboptimal count of activities.Final Answer:
Sorting should be by finish time, not start time -> Option CQuick Check:
Sort by finish time for correct greedy selection [OK]
- Sorting by start time instead of finish time
- Using > instead of >= in condition (less critical)
- Incorrect initialization of count
const activities = [
{start: 2, finish: 3},
{start: 1, finish: 4},
{start: 5, finish: 7},
{start: 6, finish: 9},
{start: 8, finish: 10},
{start: 9, finish: 11}
];What is the maximum number of non-overlapping activities that can be selected?
Solution
Step 1: Sort activities by finish time
Sorted activities by finish time ascending: [{start:2, finish:3}, {start:1, finish:4}, {start:5, finish:7}, {start:6, finish:9}, {start:8, finish:10}, {start:9, finish:11}].Step 2: Select activities greedily
Select (2,3), then (5,7), then (8,10), then (9,11) overlaps with (8,10) so skip; but (6,9) overlaps with (5,7) so skip. Total count is 4.Step 3: Check for more selections
Others overlap and cannot be selected without violating non-overlap. Maximum count is 4.Final Answer:
4 -> Option BQuick Check:
Max non-overlapping activities = 4 [OK]
- Not sorting activities before selection
- Selecting overlapping activities
- Ignoring start time conditions
Ready to prove it?
Pass the test and this pattern moves unknown
