Leetcode买卖股票系列题小结(Python)

121.买卖股票的最佳时机

点评:整个思考化简过程还是没有跳出整个框架。k=1的时候通过写上发现k这个状态可以去掉,初始化正好也有机的结合到了转移方程中,最后例行优化空间。

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        #状态,选择。有三种状态,第几天,第几次交易。三种状态转换,buy、sell、rest,使得在0-1间转换。
        #dp[i][k][0]和dp[i][k][1]分别代表第i天,第k次交易的最大利润。
        #转移方程(根据状态自动机可以写出):dp[i][k][0]= max(dp[i-1][k][0], dp[i-1][k][1]+price)  dp[i][k][1] = max(dp[i-1][k][1], dp[i-1][k-1][0]-price)
        #初始化 判断i-1=-1的时,dp[i][k][0] = 0,dp[i][k][1] = -price
        #3
        #2
        #1
        #GO!
        N = len(prices)
        dp = [[0 for i in range(2)] for j in range(N)]
        dp_i_0, dp_i_1 = 0, float('-inf')
        for i in range(N):
            dp_i_0 = max(dp_i_0, dp_i_1+prices[i])
            dp_i_1 = max(dp_i_1, -prices[i])
        return dp_i_0

122. 买卖股票的最佳时机 II
点评:k等于无限,也不需要记录k状态。

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        #有了第一题的基础,直接开干!!!
        N = len(prices)
        dp_i_0, dp_i_1 = 0, float('-inf')
        for i in range(N):
            if i - 1 == -1:
                dp_i_0 = 0
                dp_i_1 = -prices[i]
                continue
            dp_i_0 = max(dp_i_0, dp_i_1 + prices[i])
            dp_i_1 = max(dp_i_1, dp_i_0- prices[i])
        return dp_i_0

123. 买卖股票的最佳时机 III
点评:k=2,需要考虑k,并且是从后往前考虑,因为k的时候需要k-1时候的状态。

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        N = len(prices)
        if N == 0:return 0
        dp = [[[0 for j in range(2)] for k in range(2+1)] for i in range(N)]
        for i in range(N):
            for k in range(2, 0, -1):
                if i-1==-1:
                    dp[i][1][0], dp[i][0][1] = 0, float('-inf')
                    dp[i][1][0], dp[i][1][1] = 0, -prices[i]
                    dp[i][2][0], dp[i][2][1] = 0, -prices[i]
                    continue
                dp[i][k][0] = max(dp[i-1][k][0], dp[i-1][k][1]+prices[i])
                dp[i][k][1] = max(dp[i-1][k][1], dp[i-1][k-1][0]-prices[i])
        return dp[-1][-1][0]

188. 买卖股票的最佳时机 IV
点评:k无限的时候,这里需要考虑一个用例。即k大于n/2的,因为至少没两次交易才能完整表示输入输出,所以大于n/2的视为无限,而无限可以减少空间和k状态这一维度的时间复杂度。

class Solution:
    def maxProfit(self, k: int, prices: List[int]) -> int:
        N = len(prices)
        if N == 0:return 0
        def maxProfit_k_inf(prices):
            dp_i_0, dp_i_1 = 0, -float('inf')
            for price in prices:
                t = dp_i_0
                dp_i_0 = max(dp_i_0, dp_i_1+price)
                dp_i_1 = max(dp_i_1, dp_i_0-price)
            return dp_i_0
        if k > N // 2:
            return maxProfit_k_inf(prices)
        dp = [[[0 for j in range(2)] for kk in range(k+1)]for i in range(N)]
        for i in range(N):
            if i - 1 == -1:
                    dp[i][0][0], dp[i][0][1] = 0, float('-inf')
                    for j in range(1, k+1):
                        dp[i][j][0], dp[i][j][1] = 0, -prices[i]
                    continue
            for kk in range(k, 0, -1):
                dp[i][kk][0] = max(dp[i-1][kk][0], dp[i-1][kk][1]+prices[i])
                dp[i][kk][1] = max(dp[i-1][kk][1], dp[i-1][kk-1][0]-prices[i])
        return dp[-1][-1][0]

309.最佳买卖股票时机含冷冻期
点评:状态转移方程改一下。

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        N = len(prices)
        if N == 0:return 0
        dp = [[0 for j in range(2)] for i in range(N)]
        for i in range(N):
            if i - 1 == -1:
                dp[i][0], dp[i][1] = 0, -prices[i]
                continue
            dp[i][0] = max(dp[i-1][0], dp[i-1][1]+prices[i])
            dp[i][1] = max(dp[i-1][1], dp[i-2][0]-prices[i])
        return dp[-1][0]

714.买卖股票的最佳时机含手续费
点评:每次买入或卖出的时候减一个手续费。

class Solution:
    def maxProfit(self, prices: List[int], fee: int) -> int:
        N = len(prices)
        if N == 0:return 0
        dp = [[0 for j in range(2)] for i in range(N)]
        for i in range(N):
            if i - 1 == -1:
                dp[i][0], dp[i][1] = 0, -prices[i]-fee
                continue
            dp[i][0] = max(dp[i-1][0], dp[i-1][1]+prices[i])
            dp[i][1] = max(dp[i-1][1], dp[i-1][0]-prices[i]-fee)
        return dp[-1][0]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值