package
0.0.0-20241220224003-b7cf03a90b2b
Repository: https://github.com/szhou12/leetcode-go.git
Documentation: pkg.go.dev
# README
1235. Maximum Profit in Job Scheduling
Solution idea
Greedy (sorting by end date) + DP (2-D) + Binary Search (UpperBound)
- Greedy (sorting by end date)
- 此题涉及 "non-overlapping intervals" 的问题。大概率需要要尝试 "sort by end date"。马上应该联想到的例题是: 435. Non-overlapping Intervals
- :arrow_right: 用Greedy解决 "non-overlapping intervals" 问题的一个核心前提是一定会选择第一个job。
- :arrow_right: BUT! 对于本题,因为要求第二个维度,也就是利益的最大化,总是选择第一个job(时间线上最早的)并不是铁定最优解。
- :arrow_right: 所以,不能用Greedy无脑解决。
- :arrow_right: Greedy无脑解行不通,那么,就尝试DP的暴力解。同时,sort by end date这个思路依然可以沿用:一是保证了之后DP定义(在endTime维度上)的单增性;二是保证了可以使用Binary Search来进行快速的"回头看"
- DP (2-D)
dp[i]
可以有两种定义。用第二种定义可以优化时间复杂度。dp[i] :=
max profit if we MUST take jobi
dp[i] = max(dp[j] + profit[i])
wherej
are all compatible jobs withi
(i.e.endTime[j] <= startTime[i]
).dp[i]
not necessarily monotonic increasing. Thus, need to all possiblej
for eachi
.- Time complexity:
O(n^2)
dp[i] :=
max profit at jobi
's endTime (may or may not include jobi
's profit)dp[i] = max(dp[j] + profit[i], dp[i-1])
wherej
is the latest (WHY?) job that is compatible withi
.- WHY can
j
be just the latest? Becausedp[i]
in this definition is monotonic increasing. The max profit is only gonna increase as time goes by. Thus, the latest compatiblej
is giving the higher profit than any earlier compatible jobs. - Time complexity:
O(nlogn)
by using Binary Search (UpperBound).
- Binary Search (UpperBound)
- Jobs are sorted by end time + Using 2nd definition of
dp[i]
=> We can use Binary Search to efficiently find the latest compatible jobj
fori
upperBound(nums []int, target int)
gives the first indexi
s.t.nums[i] > target
. The latest compatible jobj
is defined asendTime[j] <= startTime[i]
. Thus,i-1
is what we want.- 魔改
upperBound(nums []int, target int)
asupperBound(dp [][]int, target int)
dp = [[endTime at job 0, maxProfit], [endTime at job 1, maxProfit], ...]
target = startTime[i]
Time complexity = $O(n\log n)$