- 题目解析:
题目如下:给定一个数组,数组中的第 i 个元素代表第 i 天的股票价格。有以下规则:可多次买卖股票,每次卖出股票后存在一天的冷冻期(冷冻期内小R不能购买股票),在买入新的股票前必须卖出之前的股票。求最大利润。
思路:可以看成卖出、买入、冷冻期,三次一轮回,原先思路,我是将一个流程包括三个状态,那么至少需要三天完成,即一天买入、一天卖出、一天冷冻期。若两天则比较大小就可以计算了。然后按照总天数,按照数列排序,用二维数组进行计算。然后发现代码非常的冗长,而且到后面逻辑会有些紊乱。 新思路:根据豆包的思路提醒,
她的三个状态应该分成:
- hold[i]:第 i 天结束时持有股票的最大利润。
- sold[i]:第 i 天结束时不持有股票且不在冷冻期的最大利润。
- rest[i]:第 i 天结束时在冷冻期的最大利润。
初始时,我们设定第一天的状态:持有股票的状态为-当天股票价格(因为买入需要支付成本),刚卖出股票的状态为0(因为第一天不可能卖出),不进行任何操作的状态也为0(因为没有进行任何操作)。对于后续的天数,我们根据状态转移方程更新这三个状态的值。
虽然差不多,但是有点出入,分析点在于那天是否持有股票、是否在冷冻期,而我的切入点只是单纯的是买入卖出的时候。接下来是状态转移的变化:
- hold[i] 可以从 hold[i-1](继续持有)或 rest[i-1] - stocks[i](买入股票)转移而来。
- sold[i] 可以从 hold[i-1] + stocks[i](卖出股票)转移而来。
- rest[i]可以从 sold[i-1](冷冻期)或 rest[i-1](继续冷冻期)转移而来。
在最后一天,小R要么持有现金(不进行任何操作或刚卖出股票的状态),要么持有股票(但不可能,因为持有股票意味着最后一天没有卖出,而卖出后有冷冻期,所以最后一天不可能持有股票)。因此,最终答案为最后一天不进行任何操作或刚卖出股票的状态中的较大值。
关键步骤:
- hold[i] = max(hold[i-1], rest[i-1] - stocks[i]):表示第 i 天持有股票的最大利润。
- sold[i] = hold[i-1] + stocks[i]:表示第i 天卖出股票的最大利润。
- rest[i] = max(rest[i-1], sold[i-1]):表示第 i 天在冷冻期的最大利润。
虽然同样是三个状态,但是我的思考方向还是有所不对。豆包很好的解决了我的纠结,避免我陷入死胡同。
最后豆包给的代码是:
def solution(stocks):
if not stocks:
return 0
n = len(stocks)
hold = [0] * n
sold = [0] * n
rest = [0] * n
# 初始化状态
hold[0] = -stocks[0]
sold[0] = 0
rest[0] = 0
for i in range(1, n):
# 更新 hold[i]
hold[i] = max(hold[i-1], rest[i-1] - stocks[i])
# 更新 sold[i]
sold[i] = hold[i-1] + stocks[i]
# 更新 rest[i]
rest[i] = max(rest[i-1], sold[i-1])
# 最终结果
return max(sold[n-1], rest[n-1])