当前位置:   article > 正文

leetcode-动态规划【股票问题】_股票问题leetcode

股票问题leetcode

目录

121. 买卖股票的最佳时机(只能买卖一次)

122. 买卖股票的最佳时机ii (可以买卖多次)

123. 买卖股票的最佳时机iii (最多买卖两次)

188. 买卖股票的最佳时机iv (最多买卖k次)

309. 最佳买卖股票时机含冷冻期(买卖多次,卖出有一天冷冻期)

714. 买卖股票的最佳时机含手续费(买卖多次,每次有手续费)


1. 用dp[i][0]表示第i天持有股票所得最多现金,dp[i][1]表示第i天不持有股票所得最多现金。

2. 确定递推公式

第i天持有股票所得最多现金dp[i][0], 可以由两个状态推出来

  • 第i-1天持有股票:dp[i - 1][0]
  • 第i天买入股票:-prices[i]

dp[i][0] = max(dp[i - 1][0], -prices[i]);

第i天不持有股票所得最多现金dp[i][1], 也可以由两个状态推出来

  • 第i-1天就不持有股票:dp[i - 1][1]
  • 第i天卖出股票:dp[i - 1][0] + prices[i]

dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i]);

3. 初始化dp数组:dp[0][0] -= prices[0],dp[0][1] = 0

121. 买卖股票的最佳时机(只能买卖一次)

  1. class Solution(object):
  2. def maxProfit(self, prices):
  3. """
  4. :type prices: List[int]
  5. :rtype: int
  6. """
  7. n = len(prices)
  8. if n < 2:
  9. return 0
  10. profit = 0
  11. # 存储第i天卖出时的最低买入价
  12. dp = [0 for _ in range(n)]
  13. dp[0] = prices[0]
  14. for i in range(1, n):
  15. dp[i] = min(dp[i-1], prices[i])
  16. profit = max(profit, prices[i]-dp[i])
  17. return profit
  1. # 按照公式流程
  2. class Solution(object):
  3. def maxProfit(self, prices):
  4. """
  5. :type prices: List[int]
  6. :rtype: int
  7. """
  8. if len(prices) < 2: return 0
  9. # dp[i][0]存储第i天持有股票所得最多现金
  10. # dp[i][1]存储第i天不持有股票所得最多现金
  11. dp = [[-prices[0], 0]]
  12. for i in range(1, len(prices)):
  13. # dp[i-1][0]:第i-1天买入/持有,第i天继续持有
  14. # -prices[i]:第i天买入
  15. res0 = max(dp[i-1][0], -prices[i])
  16. # dp[i-1][1]:第i-1天非持有,第i天继续非持有
  17. # dp[i-1][0]+prices[i]:第i天卖出
  18. res1 = max(dp[i-1][1], dp[i-1][0]+prices[i])
  19. dp.append([res0, res1])
  20. return dp[-1][1]

122. 买卖股票的最佳时机ii (可以买卖多次)

  1. # 贪心算法
  2. class Solution(object):
  3. def maxProfit(self, prices):
  4. """
  5. :type prices: List[int]
  6. :rtype: int
  7. """
  8. ans = 0
  9. pre = prices[0]
  10. for i in range(len(prices)):
  11. if prices[i] > pre:
  12. ans += prices[i] - pre
  13. pre = prices[i]
  14. return ans
  1. class Solution(object):
  2. def maxProfit(self, prices):
  3. """
  4. :type prices: List[int]
  5. :rtype: int
  6. """
  7. # res0持有,res1不持有
  8. dp = [[-prices[0], 0]]
  9. for i in range(1, len(prices)):
  10. # dp[i-1][0]:第i-1天买入/持有,第i天继续持有
  11. # dp[i-1][1]-prices[i]:第i天买入 + 之前买卖的利润
  12. res0 = max(dp[i - 1][0], dp[i-1][1]-prices[i])
  13. # dp[i-1][1]:第i-1天非持有,第i天继续非持有
  14. # dp[i-1][0]+prices[i]:第i天卖出
  15. res1 = max(dp[i - 1][1], dp[i - 1][0] + prices[i])
  16. dp.append([res0, res1])
  17. return dp[-1][1]

123. 买卖股票的最佳时机iii (最多买卖两次)

dp[i][j]表示第i天的第j个状态所持有的最大现金,每天有5个状态:

0:没有操作

1:第一次买入/持有:dp[i][1] = max(dp[i-1][0] - prices[i], dp[i - 1][1])

2:第一次卖出:dp[i][2] = max(dp[i - 1][1] + prices[i], dp[i - 1][2])

3:第二次买入/持有:dp[i][3] = max(dp[i - 1][3], dp[i - 1][2] - prices[i])

4:第二次卖出:dp[i][4] = max(dp[i - 1][4], dp[i - 1][3] + prices[i])

初始化:dp[0] = [0, -prices[0], 0, -prices[0], 0],注意这里dp[0][3]相当于在第一天买入卖出后又买入了一次,所以应该是 -prices[0]

  1. class Solution(object):
  2. def maxProfit(self, prices):
  3. """
  4. :type prices: List[int]
  5. :rtype: int
  6. """
  7. # 0:没有操作
  8. # 1:第一次买入/持有
  9. # 2:第一次卖出
  10. # 3:第二次买入/持有
  11. # 4:第二次卖出
  12. dp = [[0, -prices[0], 0, -prices[0], 0]]
  13. for i in range(1, len(prices)):
  14. res0 = dp[i-1][0]
  15. res1 = max(dp[i-1][1], dp[i-1][0] - prices[i])
  16. res2 = max(dp[i-1][2], dp[i-1][1] + prices[i])
  17. res3 = max(dp[i-1][3], dp[i-1][2] - prices[i])
  18. res4 = max(dp[i-1][4], dp[i-1][3] + prices[i])
  19. dp.append([res0, res1, res2, res3, res4])
  20. return dp[-1][-1]

188. 买卖股票的最佳时机iv (最多买卖k次)

  1. class Solution(object):
  2. def maxProfit(self, k, prices):
  3. """
  4. :type k: int
  5. :type prices: List[int]
  6. :rtype: int
  7. """
  8. if k == 0 or len(prices) < 2: return 0
  9. # 0:没有操作
  10. # 1:第一次买入/持有
  11. # 2:第一次卖出
  12. # ...
  13. # 2k-1:第k次买入/持有
  14. # 2k:第k次卖出
  15. dp = [[0 for _ in range(2*k+1)] for _ in range(len(prices))]
  16. for j in range(1, 2*k, 2):
  17. dp[0][j] = -prices[0]
  18. for i in range(1, len(prices)):
  19. for j in range(0, 2 * k - 1, 2):
  20. # 买入/持有
  21. dp[i][j + 1] = max(dp[i - 1][j + 1], dp[i - 1][j] - prices[i])
  22. # 卖出/非持有
  23. dp[i][j + 2] = max(dp[i - 1][j + 2], dp[i - 1][j + 1] + prices[i])
  24. return dp[-1][-1]

309. 最佳买卖股票时机含冷冻期(买卖多次,卖出有一天冷冻期)

  1. class Solution(object):
  2. def maxProfit(self, prices):
  3. """
  4. :type prices: List[int]
  5. :rtype: int
  6. """
  7. # dp[持有,非持有]
  8. dp = [[0, 0] for _ in range(len(prices))]
  9. dp[0] = [-prices[0], 0]
  10. for i in range(1, len(prices)):
  11. if i == 1:
  12. dp[i][0] = max(dp[i - 1][0], -prices[i])
  13. else:
  14. dp[i][0] = max(dp[i - 1][0], dp[i - 2][1] - prices[i])
  15. dp[i][1] = max(dp[i-1][1], dp[i-1][0]+prices[i])
  16. return dp[-1][-1]

714. 买卖股票的最佳时机含手续费(买卖多次,每次有手续费)

  1. class Solution(object):
  2. def maxProfit(self, prices, fee):
  3. """
  4. :type prices: List[int]
  5. :type fee: int
  6. :rtype: int
  7. """
  8. dp = [[0,0] for _ in range(len(prices))]
  9. dp[0] = [-prices[0], 0]
  10. for i in range(1, len(prices)):
  11. dp[i][0] = max(dp[i-1][0], dp[i-1][1] - prices[i])
  12. dp[i][1] = max(dp[i-1][1], dp[i-1][0] + prices[i] - fee)
  13. return dp[-1][-1]
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/煮酒与君饮/article/detail/816231
推荐阅读
相关标签
  

闽ICP备14008679号