Browse curriculum

FAANGPrep Sprint

Maximum Profit in Job Scheduling

Given n jobs where every job has a start time, end time, and profit, return the maximum profit without overlapping jobs.

Examples

Input:startTime = [1,2,3,3], endTime = [3,4,5,6], profit = [50,10,40,70]
Output:120
Explain:

Take the job ending at 3 for 50 and the one starting at 3 for 70. They touch but do not overlap.

Input:startTime = [1,2,3,4,6], endTime = [3,5,10,6,9], profit = [20,20,100,70,60]
Output:150
Explain:

The 100 job runs too long to fit with anything else, so 20 + 70 + 60 wins instead.

Input:startTime = [1,1,1], endTime = [2,3,4], profit = [5,6,4]
Output:6
Explain:

All three start at the same time, so only one can be taken — the best-paying one.

Problem Understanding

We have jobs (start, end, profit). We want to pick a subset of non-overlapping jobs to maximize total profit.

Example:

  • Job 1: [1, 3], Profit 50
  • Job 2: [2, 4], Profit 10
  • Job 3: [3, 5], Profit 40
  • If we pick Job 1, we can't pick Job 2 (overlap). We CAN pick Job 3.
  • Total: 90.

Algorithm Strategy

  1. Sort the jobs by end time. dp[i] is then the best profit obtainable from the first i jobs in that order.
  2. For job i there are exactly two choices, and together they cover everything:
    • Leave it: whatever the first i-1 jobs managed — dp[i-1].
    • Take it: its profit, plus the best from every job that finishes no later than it starts.
  3. dp[i] = max(take, leave), and dp[n] is the answer.

Why sort by end time? The recurrence needs "the best using only jobs that finish by time t". After sorting by end time, those jobs are always a prefix — so a single index locates the answer in dp.

Why binary search? That prefix's length is exactly the count of jobs ending at or before this job's start, and the end times are sorted, so it is found in O(log n) instead of a backward scan. With n up to 50,000 that is the difference between passing and timing out.

Interactive Visualization

SORTED BY END TIME, SO EVERY COMPATIBLE JOB IS A BLOCK FROM THE TOP · OUTLINED = WHAT THE BINARY SEARCH COUNTED

SORT BY END TIME

jobs, sorted by end time

1-3

50

2-4

10

3-5

40

3-6

70

1

6

dp — best profit using the first i jobs

0

1

2

3

4

0
-
-
-
-

take it

—

leave it

—

Answer

—

the rule

idx = jobs ending by start[i]
include = pay[i] + dp[idx]
exclude = dp[i-1]
dp[i] = max(include, exclude)

 

Sort the 4 jobs by end time: 1-3, 2-4, 3-5, 3-6. With no jobs at all the profit is 0, so dp[0] = 0

Next

Job 1 runs 1 to 3 and pays 50. Take it, or leave it?

jobs

The jobs are drawn in the order the algorithm sorts them — by end time, top to bottom — with dp underneath.

On a search step, every job ending at or before the current job's start is outlined at once. Because of the sort they are always a block from the top, and the size of that block is the dp index the binary search returns. That is the whole trick.

Try Long: three short jobs reach 85 and one long one pays 90, so taking the most jobs loses.