You can implement it in O(nlogn)
complexity, assuming that the start time, end time, and duration of the interval are i[0]
, i[1]
, and i[2]
, respectively, and you can implement it with this algorithm。
expl
The final selected intervals must be non-overlapping, and as a rule of thumb, the intervals are sorted by endTime.
Suppose we traverse each interval in the order it was sorted as above. We would like to think that if we chose the ith interval then we would have the opportunity to update such a record dp[endTime[i]]
, where dp[time]
denotes the maximum gain up to the moment of time. Obviously, we would have dp[endTime[i]] = dp[startTime[i]] + profit[i]
.
Of course, we can't store the value of the maximum benefit at every moment in dp, we can only discretize it to store the maximum benefit at every endTime moment. That is, dp should be a hash table.
Thus, it is possible that there is no startTime[i]
in the dp record, but we just need to find the last moment that is less than or equal to startTime[i]
, denoted as t, which corresponds to dp[t] = val
.
In particular, note that our attempt to record dp[endTime[i]] = val + profit[i]
presupposes that val + profit[i]
must be greater than the last moment inside dp. That is, we only store time->profit
key-value pairs inside the dp that are incremented by profit. In fact, it makes sense that if t0<t1
and dp[t0]>dp[t1]
, there's no need fort1
to be stuffed into the dp array (wasting time and decreasing returns).
Thus our algorithm comes to life. For the current interval i, we look inside the dp array (or ordered map) at the maximum gain val before the moment startTime[i]
, which we can get by binary search
. Next, we have the opportunity to add dp[endTime[i]] = val+profit[i]
. Note that there is another possibility if the optimal solution of dp[endTime[i]] is not to take the ith interval, in which case dp[endTime[i]] = dp[endTime[i-1]]
.
With such a sequence dp that is increasing in both time and gain, we can keep appending records of dp[endTime[i]]
to create the maximum gain at the moment of update.
The implementation is as follows
class Solution {
static bool cmp(vector<int>& a, vector<int>& b)
{
return a[1] < b[1];
}
public:
int jobScheduling(vector<int>& s, vector<int>& e, vector<int>& v)
{
int n = s.size();
vector<vector<int>>jobs;
for (int i = 0; i < n; i++) jobs.push_back({ s[i],e[i],v[i] });
sort(jobs.begin(), jobs.end(), cmp);
map<int, int>dp;
dp[-1] = 0;
int ret = 0;
for (int i = 0; i < n; i++)
{
int ans = ret;
auto iter = dp.upper_bound(jobs[i][0]);
ans = max(ans, prev(iter, 1)->second + jobs[i][2]);
dp[jobs[i][1]] = ans;
ret = max(ret, ans);
}
return ret;
}
};
Here are some relevant questions
leetcode:1235. Maximum Profit in Job Scheduling