LeetCode专题(二)--股票买卖问题

121.买卖股票的最佳时机思路描述      对于上述的描述而言,我们有两种思路:找到下一个时间点与当前时间点的差值,只考虑将最大的股票价格减去最小的股票价格使用DP的方式进行动态规划转移      由于我本人对于DP较为感兴趣,所以我们使用第二种方法来解题,解题的...
摘要由CSDN通过智能技术生成

121.买卖股票的最佳时机

在这里插入图片描述

思路描述

      对于上述的描述而言,我们有两种思路:

  • 找到下一个时间点与当前时间点的差值,只考虑将最大的股票价格减去最小的股票价格
  • 使用DP的方式进行动态规划转移
          由于我本人对于DP较为感兴趣,所以我们使用第二种方法来解题,解题的思路如下:
  • step1.先定义动态转移方程,我们可以设第 i i i 天的最大利润是 max profit,而这个最大利润我们简记为MP,那么MP的动态转移方程就与前一天的动态转移方程有关,所以 M P [ i ] = M P [ i − 1 ] + i s b u y o r n o t MP[i]=MP[i-1]+isbuyornot MP[i]=MP[i1]+isbuyornot       这里的 i s b u y o r n o t isbuyornot isbuyornot 非常麻烦,所以在MP坐标轴上引入多一维的空间表达,这个空间表达为 M P [ i ] [ j ] MP[i][j] MP[i][j] ,那么 M P [ i ] [ j ] MP[i][j] MP[i][j] 中的 j j j 代表着三种状态:
    • 0:不动
    • 1:买入
    • 2:卖出
            设 a [ i ] a[i] a[i] 是我们的 l i s t list list列表,那么动态转移方程从原来的第 i i i天金额的变换为第 i − 1 i-1 i1天加上股票的买卖,公式定义如下:
      M P [ i ] = { M P [ i ] = M P [ i − 1 ] + ( − a [ i ] ) M P [ i ] = M P [ i − 1 ] + a [ i ] MP[i]=\left\{ \begin{aligned} MP[i] & = & MP[i-1] + (-a[i]) \\ MP[i] & = & MP[i-1] + a[i] \end{aligned} \right. MP[i]={MP[i]MP[i]==MP[i1]+(a[i])MP[i1]+a[i]
            转换为第 i i i天中手上是否持有股票, 0 0 0代表无, 1 1 1代表有:
      M P [ i , 0 ] = { M P [ i , 0 ] = M P [ i − 1 , 1 ] + a [ i ] M P [ i , 0 ] = M P [ i − 1 , 0 ] MP[i, 0]=\left\{ \begin{aligned} MP[i,0] & = & MP[i-1,1] + a[i] \\ MP[i,0] & = & MP[i-1, 0] \end{aligned} \right. MP[i,0]={MP[i,0]MP[i,0]==MP[i1,1]+a[i]MP[i1,0]
      M P [ i , 1 ] = { M P [ i , 1 ] = M P [ i − 1 , 0 ] + ( − a [ i ] ) M P [ i , 1 ] = M P [ i − 1 , 1 ] MP[i, 1]=\left\{ \begin{aligned} MP[i,1] & = & MP[i-1,0] + (-a[i]) \\ MP[i,1] & = & MP[i-1, 1] \end{aligned} \right. MP[i,1]={MP[i,1]MP[i,1]==MP[i1,0]+(a[i])MP[i1,1]
            总体表达后,就可以使用矩阵来代表动态转移方程的变换,行代表第 i i i 步操作(与已知的股票序列长度有关),列代表第 i i i步执行操作后所得到的状态,由于只计算一次,那么找到其中的最大值即可:
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        if not prices: return 0
        res = 0
        profit = [[0 for i in range(3)] for i in range(len(prices))]
        profit[0][0], profit[0][1], profit[0][2] = 0, -prices[0], 0
        for i in range(1, len(prices)):
            profit[i][0] = 0
            profit[i][1] = max(profit[i-1][1], profit[i-1][0] - prices[i])
            profit[i][2] = profit[i-1][1] + prices[i]
            res = max(res,profit[i][0], profit[i][1], profit[i][2])
        return res

查看执行效率:
在这里插入图片描述
      对于Python而言,这可不是一个很光彩的执行效率,所以尽量的使用第一种思想来操作:
在这里插入图片描述

123.买卖股票的最佳时机 III

      题目描述:
在这里插入图片描述
      这里可以增加多一个维度,这个维度是买卖了多少次,也就是说,由原来的 M P [ i ] [ j ] MP[i][j] MP[i][j] 变换成 M P [ i ] [ j ] [ k ] MP[i][j][k] MP[i][j][k],其中 k k k 代表了买卖了多少次,方程也可以表达为 M P [ i ] [ k ] [ j ] MP[i][k][j] MP[i][k][j]
M P [ i , k , 0 ] = { M P [ i , k , 0 ] = M P [ i − 1 , k , 0 ] M P [ i , k , 0 ] = M P [ i − 1 , k − 1 , 1 ] + a [ i ] MP[i, k, 0]=\left\{ \begin{aligned} MP[i, k, 0] & = & MP[i-1, k, 0] \\ MP[i, k, 0] & = & MP[i-1, k-1, 1] + a[i] \end{aligned} \right. MP[i,k,0]={MP[i,k,0]MP[i,k,0]==MP[i1,k,0]MP[i1,k1,1]+a[i]
M P [ i , k , 1 ] = { M P [ i , k , 1 ] = M P [ i − 1 , k , 1 ] M P [ i , k , 1 ] = M P [ i − 1 , k − 1 , 0 ] − a [ i ] MP[i, k, 1]=\left\{ \begin{aligned} MP[i, k, 1] & = & MP[i-1, k, 1] \\ MP[i, k, 1] & = & MP[i-1, k-1, 0] - a[i] \end{aligned} \right. MP[i,k,1]={MP[i,k,1]MP[i,k,1]==MP[i1,k,1]MP[i1,k1,0]a[i]
      最后状态: max ⁡ M P [ n , 0 , . . . , k , 0 ] \max{MP[n, {0,...,k}, 0]} maxMP[n,0,...,k,0]

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        if not prices: return 0
        profit = [[[0 for _ in range(2)] for _ in range(3)] for _ in range(len(prices))]
        profit[0][0][0], profit[0][0][1] = 0, -prices[0]
        profit[0][1][0], profit[0][1][1] = -sys.maxsize, -sys.maxsize
        profit[0][2][0], profit[0][2][1] = -sys.maxsize, -sys.maxsize

        for i in range(1, len(prices)):
            profit[i][0][0] = profit[i-1][0][0]
            profit[i][0][1] = max(profit[i-1][0][1], profit[i-1][0][0] - prices[i])
            profit[i][1][0] = max(profit[i-1][1][0], profit[i-1][0][1] + prices[i])
            profit[i][1][1] = max(profit[i-1][1][1], profit[i-1][1][0] - prices[i])
            profit[i][2][0] = max(profit[i-1][2][0], profit[i-1][1][1] + prices[i])

        end = len(prices) - 1
        return max(profit[end][0][0], profit[end][1][0], profit[end][2][0])
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值