GREEDY › PART I
Open — the attempt gate is not wired up yet
This editorial is meant to unlock after you have run the problem at least once, with the worked solution behind one further deliberate click. That needs per-learner unlock state nothing stores today, so for now the whole article is open.
Try it yourself first →A chosen activity blocks the person until its finish time. Among all activities that can be chosen next, the one that finishes earliest leaves at least as much time available for every later activity as any other choice. Choosing an activity that finishes later can only remove possibilities; it never creates one.
That gives a greedy rule: repeatedly choose the compatible activity with the smallest finish time. Sorting all activities by finish time makes that choice visible from left to right. When an activity starts strictly after the last selected finish, accept it and update the boundary; otherwise, skip it because it cannot improve the current schedule.
| MEASURE | BOUND | WHY |
|---|---|---|
| Time | O(n log n) | Building the paired list takes one pass, sorting performs O(n log n) comparisons, and the final scan examines each activity once. The sorting work dominates, and no activity is rescanned. |
| Space | O(n) extra | The paired activity list stores one pair for each input activity, while sorting uses at most O(n) additional working space depending on the implementation. The returned count is a scalar, so there is no output array to exclude; the bound remains O(n) in every input shape. |
#include <algorithm>
#include <utility>
#include <vector>
using namespace std;
class Solution {
public:
int activitySelection(vector<int>& start, vector<int>& finish) {
vector<pair<int, int>> activities;
activities.reserve(start.size());
for (int i = 0; i < static_cast<int>(start.size()); ++i) {
activities.push_back({finish[i], start[i]});
}
sort(activities.begin(), activities.end());
int lastFinish = -1;
int answer = 0;
for (const auto& activity : activities) {
int currentFinish = activity.first;
int currentStart = activity.second;
if (currentStart > lastFinish) {
++answer;
lastFinish = currentFinish;
}
}
return answer;
}
};The pair stores finish first so the default sort puts the activity with the earliest finish at the front. The original start and finish arrays are not sorted independently; each index remains one intact activity. The strict comparison currentStart > lastFinish is the exact scheduling rule, so an activity beginning at the previous finish is correctly rejected.