Maximum Profit in Job Scheduling

Sort jobs by end; dp[i] = max(skip dp[i-1], take profit + dp[predecessor end ≤ start]); binary-search the predecessor.

Hard
Time O(n log n) Space O(n)
LeetCode
5 min read
dp binary-search sorting intervals

Problem#

Each job has start, end, profit. You can’t run overlapping jobs. Maximize total profit.

Examples#

  • startTime=[1,2,3,3], endTime=[3,4,5,6], profit=[50,10,40,70]120.
  • start=[1,1,1], end=[2,3,4], profit=[5,6,4]6.

Constraints#

  • 1 <= jobs <= 5 * 10^4.

Approach#

Sort jobs by end time. dp[i] = best profit considering jobs 0..i. Choice: skip job i (dp[i-1]) or take it (profit[i] + dp[j] where j is the latest job with end <= start[i]). Binary-search for j.

Solution#

Maximum Profit in Job Scheduling
class Solution {
public:
int jobScheduling(vector<int>& s, vector<int>& e, vector<int>& p) {
int n = s.size();
vector<tuple<int,int,int>> jobs(n);
for (int i = 0; i < n; ++i) jobs[i] = {e[i], s[i], p[i]};
sort(jobs.begin(), jobs.end());
vector<int> ends(n);
for (int i = 0; i < n; ++i) ends[i] = get<0>(jobs[i]);
vector<int> dp(n + 1, 0);
for (int i = 0; i < n; ++i) {
auto [end, start, profit] = jobs[i];
int j = upper_bound(ends.begin(), ends.begin() + i, start) - ends.begin();
// j is count of jobs with end <= start; their best is dp[j]
dp[i + 1] = max(dp[i], dp[j] + profit);
}
return dp[n];
}
};

Editorial#

After sorting by end, “the latest non-conflicting job” is found via upper_bound on the end-time array — the first job whose end exceeds start[i], so the count of valid predecessors is its index. The DP is then a clean take-or-skip.

Complexity#

  • Time: O(n log n).
  • Space: O(n).

Concept revision#

Search ESC

Keyboard shortcuts

Shortcuts are disabled while typing in inputs.