What if you could instantly find the best schedule without checking every possibility?
Why Activity Selection Problem in DSA Go?
Imagine you have a list of meetings to attend in a day, each with a start and end time. You want to attend as many meetings as possible without any overlap. Trying to pick meetings manually by checking each one against all others is like juggling too many balls at once and easily leads to confusion.
Manually checking every meeting against all others to avoid overlaps is slow and tiring. It's easy to miss a conflict or pick fewer meetings than possible. This trial-and-error approach wastes time and often results in poor scheduling.
The Activity Selection Problem uses a smart method: sort meetings by their finish times and always pick the earliest finishing meeting that doesn't overlap with the ones already chosen. This simple rule quickly finds the maximum number of meetings you can attend without conflicts.
for i := 0; i < len(meetings); i++ { for j := i + 1; j < len(meetings); j++ { if meetings[i] overlaps meetings[j] { // complicated checks and backtracking } } }
sort.Slice(meetings, func(i, j int) bool {
return meetings[i].end < meetings[j].end
})
selected := []Meeting{meetings[0]}
for i := 1; i < len(meetings); i++ {
if meetings[i].start >= selected[len(selected)-1].end {
selected = append(selected, meetings[i])
}
}This approach lets you quickly and confidently schedule the maximum number of non-overlapping activities, saving time and avoiding conflicts.
Scheduling conference talks to attend as many as possible without missing parts of any, or booking meeting rooms efficiently so no two meetings clash.
Manual scheduling is slow and error-prone.
Sorting by finish time and greedy selection solves the problem efficiently.
Enables maximum use of available time without overlaps.
Practice
Activity Selection Problem?Solution
Step 1: Understand the problem goal
The Activity Selection Problem aims to choose activities that do not overlap in time.Step 2: Identify the objective
The objective is to select the maximum number of such non-overlapping activities.Final Answer:
Select the maximum number of activities that don't overlap -> Option CQuick Check:
Goal = Max non-overlapping activities [OK]
- Choosing activities based on longest duration
- Sorting by start time only
- Trying to maximize total duration instead of count
Solution
Step 1: Identify sorting criteria
Activities must be sorted by their finish time to apply the greedy approach.Step 2: Check Go sorting syntax
Using sort.Slice with a comparison function on finish times is correct.Final Answer:
sort.Slice(activities, func(i, j int) bool { return activities[i].finish < activities[j].finish }) -> Option DQuick Check:
Sort by finish time = sort.Slice(activities, func(i, j int) bool { return activities[i].finish < activities[j].finish }) [OK]
- Sorting by start time instead of finish time
- Using sort.Ints on struct slices
- Calling sort.Sort without implementing sort.Interface
package main
import (
"fmt"
"sort"
)
type Activity struct {
start, finish int
}
func main() {
activities := []Activity{{1, 4}, {3, 5}, {0, 6}, {5, 7}, {8, 9}, {5, 9}}
sort.Slice(activities, func(i, j int) bool { return activities[i].finish < activities[j].finish })
count := 1
lastFinish := activities[0].finish
for i := 1; i < len(activities); i++ {
if activities[i].start >= lastFinish {
count++
lastFinish = activities[i].finish
}
}
fmt.Println(count)
}Solution
Step 1: Sort activities by finish time
Sorted activities by finish: (1,4), (3,5), (0,6), (5,7), (8,9), (5,9)Step 2: Select activities greedily
Select (1,4), next (5,7) since 5 >= 4, then (8,9) since 8 >= 7. Total selected = 3.Final Answer:
3 -> Option BQuick Check:
Max non-overlapping = 3 [OK]
- Counting overlapping activities
- Not sorting by finish time
- Starting count from zero instead of one
package main
import (
"fmt"
"sort"
)
type Activity struct {
start, finish int
}
func main() {
activities := []Activity{{1, 3}, {2, 5}, {4, 7}}
sort.Slice(activities, func(i, j int) bool { return activities[i].start < activities[j].start })
count := 1
lastFinish := activities[0].finish
for i := 1; i < len(activities); i++ {
if activities[i].start >= lastFinish {
count++
lastFinish = activities[i].finish
}
}
fmt.Println(count)
}Solution
Step 1: Check sorting criteria
The code sorts activities by start time, but the greedy approach requires sorting by finish time.Step 2: Understand impact of sorting
Sorting by start time can cause incorrect selection of activities, leading to wrong count.Final Answer:
Sorting by start time instead of finish time -> Option AQuick Check:
Sort by finish time needed [OK]
- Sorting by start time
- Forgetting to update lastFinish
- Starting count at zero
[(1, 2), (3, 4), (0, 6), (5, 7), (8, 9), (5, 9)], what is the maximum number of activities that can be selected without overlap using the Activity Selection Problem approach?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), then (3,4) since 3 >= 2, then (5,7) since 5 >= 4, then (8,9) since 8 >= 7. Total selected = 4.Final Answer:
4 -> Option AQuick Check:
Max non-overlapping = 4 [OK]
- Including overlapping activities
- Not sorting by finish time
- Counting all activities without checking overlap
Ready to prove it?
Pass the test and this pattern moves unknown
