We have n jobs, where every job is scheduled to be done from startTime[i] to endTime[i], obtaining a profit of profit[i].
You're given the startTime, endTime and profit arrays, return the maximum profit you can take such that there are no two jobs in the subset with overlapping time range.
If you choose a job that ends at time X you will be able to start another job that starts at time X.
Example 1:
Input: startTime = [1,2,3,3], endTime = [3,4,5,6], profit = [50,10,40,70]
Output: 120
Explanation: The subset chosen is the first and fourth job.
Time range [1-3]+[3-6] , we get profit of 120 = 50 + 70.
Example 2:
Input: startTime = [1,2,3,4,6], endTime = [3,5,10,6,9], profit = [20,20,100,70,60]
Output: 150
Explanation:
The subset chosen is the first, fourth and fifth job.
Profit obtained 150 = 20 + 70 + 60.
- initial attemp to solve via graph
- one tasks are connected to others
- optimal solution is combination of dfs and binary search
Solution
// from solution// top down DP with memo// https://leetcode.com/problems/maximum-profit-in-job-scheduling/solutions/733167/thinking-process-top-down-dp-bottom-up-dp/
varjobScheduling=function (startTime, endTime, profit) {constjobs=newArray(startTime.length);constdp=newMap();// make a new array containing start, time and profitfor (let i =0; i <jobs.length; i++) { jobs[i] = [startTime[i], endTime[i], profit[i]]; }// sort according to start timejobs.sort((a, b) => a[0] - b[0]);returndfs(0, jobs, dp);};functiondfs(idx, jobs, dp) {// base conditionif (idx ===jobs.length) {return0; }if (dp.has(idx)) {returndp.get(idx); }// pre// given this particular job idx, find the next idx that has a non-overlapping start timelet next =binarySearch(idx, jobs);// recurselet inclProfit = jobs[idx][2] + (next ===-1?0:dfs(next, jobs, dp));let exclProfit =dfs(idx +1, jobs, dp);// postdp.set(idx,Math.max(inclProfit, exclProfit));returnMath.max(inclProfit, exclProfit);}functionbinarySearch(idx, jobs) {let lo = idx +1;let hi =jobs.length-1;while (lo <= hi) {let mid =Math.floor(lo + (hi - lo) /2);// returns the next job by comparing, mid start time to idx end timeif (jobs[mid][0] >= jobs[idx][1]) {// if start time of prev is also equals or more than idx end time, continue serachingif (jobs[mid -1][0] >= jobs[idx][1]) { hi = mid -1;// if prev job start time is less than idx end time, return } else {return mid; } } else { lo = mid +1; } }return-1;}