注册一亩三分地论坛,查看更多干货!
您需要 登录 才可以下载或查看附件。没有帐号?注册账号 
x
lz在对比646Maximum Length of Pair Chain和1235Maximum Profit in Job Scheduling这两道题(这两题中chain和job差不多一个意思,接下去统一表达为job)
这两道的区别在于,646要求上一个job的endTime<当前job的startTime;1235则是上一个job的endTime<=当前job的startTime,外加profit最大。
我先做了1235,然后做了646,然后有了关于startTime的endTime的问题
我先贴一下646的三个做法:
####方法一####
class Solution:
def findLongestChain(self, pairs: List[List[int]]) -> int:
pairs.sort() # 对startTime排序
dp = [1] * len(pairs)
for i in range(len(pairs)):
for j in range(i):
if pairs[j][1] < pairs[i][0]:
dp[i] = max(dp[i], dp[j]+1)
return dp[-1]
###方法二###
class Solution:
def findLongestChain(self, pairs: List[List[int]]) -> int:
pairs.sort(key=lambda x: x[1]) # 对endTime排序
dp = [1] * len(pairs)
for i in range(len(pairs)):
for j in range(i):
if pairs[j][1] < pairs[i][0]:
dp[i] = max(dp[i], dp[j]+1)
return max(dp)
###方法三###
class Solution:
def findLongestChain(self, pairs: List[List[int]]) -> int:
pairs.sort(key=lambda x: x[1])
self.dp = [(-1000, 0)]
for s, e in pairs:
idx = self.find_last_end(s)
self.dp.append((e, max(self.dp[idx][1] + 1, self.dp[-1][1])))
return self.dp[-1][1]
def find_last_end(self, target):
left = 0
right = len(self.dp) - 1
while left <= right:
mid = left + (right - left) // 2
if self.dp[mid][0] >= target:
right = mid - 1
else:
left = mid + 1
return left - 1 if left > 0 else left
对比一下方法一和方法二,区别在于方法一是先对startTime升序排序,方法二是先对endTime升序排序。到后面截然不同的是,方法一对startTime升序排序后,每一次外循环结束后dp[-1]记录的是到目前为止的最长链;而方法二对endTime升序排序后,每一次外循环结束后dp[-1]记录的是当前job的最长链,可能之前job的链比当前的还长,所以最后return是return max(dp)
所以我的问题一是:为啥对startTime升序排序/endTime升序排序会有这样的差异?
再接下去看我的方法三,方法三是吸取了1235这道题的灵感写的。仍然是对endTime排序,但这次dp[-1]记录的是到目前为止的最长链,所以return直接返回dp[-1]即可
所以我的问题二是:为啥对endTime升序排序后,方法二的dp[i]表示为对job_i来说最长连,而方法三的dp[i]表示为到jobi为止的最长链?
|