题目要求:
小R近期表现出色,公司决定以股票的形式给予奖励,并允许他在市场上进行交易以最大化收益。给定一个数组,数组中的第 i 个元素代表第 i 天的股票价格。小R需要设计一个算法来实现最大利润。
股票交易规则如下:
小R可以多次买卖股票,但在买入新的股票前必须卖出之前的股票。 每次卖出股票后存在一天的冷冻期,在冷冻期内小R不能购买股票。 你的任务是帮助小R计算出在遵守交易规则的情况下能够获得的最大利润。
stocks: 一个整数列表,表示连续几天内的股票价格。
测试样例
样例1:
输入:stocks = [1, 2] 输出:1
样例2:
输入:stocks = [2, 1] 输出:0
样例3:
输入:stocks = [1, 2, 3, 0, 2] 输出:3
样例4:
输入:stocks = [2, 3, 4, 5, 6, 7] 输出:5
样例5:
输入:stocks = [1, 6, 2, 7, 13, 2, 8] 输出:12
题目难度:
中等
解题语言:
python
解题思路:
首先我们要明确:
1.可以多次买卖股票,但在买入新的股票前必须卖出之前的股票。
2.每次卖出股票后存在一天的冷冻期,在冷冻期内不能购买股票。
3.数据结构选择:我们可以使用动态规划来解决这个问题。定义两个状态数组:
buy[i]:表示在第 i 天结束时,持有股票的最大利润。
sell[i]:表示在第 i 天结束时,不持有股票的最大利润。
4.遍历每一天的股票价格: 更新 buy[i]:可以选择在第 i 天买入股票(前提是前一天没有卖出),或者保持前一天的状态。 更新 sell[i]:可以选择在第 i 天卖出股票(前提是前一天持有股票),或者保持前一天的状态。 最终的最大利润是 sell 数组中的最大值。
细节提示:
buy[i] = max(buy[i-1], (sell[i-2] if i >= 2 else 0) - stocks[i]):
buy[i-1] 表示保持前一天的状态。 (sell[i-2] if i >= 2 else 0) - stocks[i] 表示在前两天卖出股票后,今天买入股票。 sell[i] = max(sell[i-1], buy[i-1] + stocks[i]):
sell[i-1] 表示保持前一天的状态。 buy[i-1] + stocks[i] 表示前一天持有股票,今天卖出股票。
那么遇见冷冻期该如何计算其对交易的影响?
冷冻期的存在意味着在卖出股票后的下一天不能买入股票。我们可以通过动态规划的状态转移来处理这个问题。
状态定义:
buy[i]:表示在第 i 天结束时,持有股票的最大利润。
sell[i]:表示在第 i 天结束时,不持有股票的最大利润。
状态转移:
buy[i] 的更新需要考虑冷冻期的影响:
如果第 i 天买入股票,那么前一天不能是冷冻期,即前两天必须卖出股票。 如果第 i 天不买入股票,那么保持前一天的状态。
sell[i] 的更新:
如果第 i 天卖出股票,那么前一天必须持有股票。 如果第 i 天不卖出股票,那么保持前一天的状态。
答题代码:
def solution(stocks):
if not stocks:
return 0
n = len(stocks)
# 初始化 buy 和 sell 数组
buy = [0] * n
sell = [0] * n
# 初始状态
buy[0] = -stocks[0] # 第一天买入股票
sell[0] = 0 # 第一天不持有股票
for i in range(1, n):
# 更新 buy[i]
buy[i] = max(buy[i-1], # 保持前一天的状态
# 前一天不持有股票且不在冷冻期,今天买入
(sell[i-2] if i >= 2 else 0) - stocks[i])
# 更新 sell[i]
sell[i] = max(sell[i-1], # 保持前一天的状态
buy[i-1] + stocks[i]) # 前一天持有股票,今天卖出
# 最终的最大利润是 sell 数组中的最大值
return sell[-1]
if __name__ == "__main__":
# You can add more test cases here
print(solution([1, 2]) == 1 )
print(solution([2, 1]) == 0 )
print(solution([1, 2, 3, 0, 2]) == 3 )
print(solution([2, 3, 4, 5, 6, 7]) == 5 )
print(solution([1, 6, 2, 7, 13, 2, 8]) == 12 )