Day 49 DP:121|122|123|188. 股票 I II III IV

121. 买卖股票的最佳时机

  • 思路
    • example
    • 交易一次
    • 贪心,找前低
  • 复杂度. 时间:O(n), 空间: O(1)
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        pre_low = prices[0]
        res = 0
        for i in range(1, len(prices)):
            res = max(res, prices[i] - pre_low)
            pre_low = min(pre_low, prices[i])
        return res
  • DP, 二维,加状态
    • dp[i][0]: 第i天持有股票 (不一定是第i天买入) 最大利润
    • dp[i][1]: 第i天不持有股票 (不一定是第i天卖出) 最大利润
    • Goal: max(dp[n-1])
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        n = len(prices)
        dp = [[0 for _ in range(2)] for _ in range(n)]
        dp[0][0] = -prices[0]
        dp[0][1] = 0
        for i in range(1, n):
            dp[i][0] = max(dp[i-1][0], -prices[i])
            dp[i][1] = max(dp[i-1][1], dp[i-1][0]+prices[i])
        return max(dp[n-1])
  • 可空间优化

122. 买卖股票的最佳时机 II

  • 思路
    • example
    • 交易次数不限
    • 贪心,累加正收益
  • 复杂度. 时间:O(n), 空间: O(1)
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        res = 0
        for i in range(1, len(prices)):
            res += max(prices[i] - prices[i-1], 0)
        return res  
  • DP, 二维,带状态

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])

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        n = len(prices)
        dp = [[0 for _ in range(2)] for _ in range(n)]
        dp[0][0] = -prices[0]
        dp[0][1] = 0
        for i in range(1, n):
            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])
        return max(dp[n-1])

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

  • 思路
    • example
    • 最多两笔交易
    • DP, 三维 (j,k可合并成一维)
      • dp[i][j][k]: 第i天,第j次交易 (j=1,2),状态k 的最大利润
        • k=0: 持有 (已买入)
        • k=1: 不持有 (已卖出)
        • 注意:先买后卖

j = 1, 2:
dp[i][j][0] = max(dp[i-1][j][0], dp[i-1][j-1][1]-prices[i])
dp[i][j][1] = max(dp[i-1][j][1], dp[i-1][j][0]+prices[i])

  • 复杂度. 时间:O(n), 空间: O(n)
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        m = 2
        dp = [[[0] * 2 for _ in range(m+1)] for _ in range(len(prices))]
        dp[0][0] = [-float('inf'), 0]
        dp[0][1] = [-prices[0], -float('inf')]
        dp[0][2] = [-float('inf'), -float('inf')]
        for i in range(1, len(prices)):
            for j in range(1, m+1):
                dp[i][j][0] = max(dp[i-1][j][0], dp[i-1][j-1][1]-prices[i])
                dp[i][j][1] = max(dp[i-1][j][1], dp[i-1][j][0]+prices[i])
        return max(dp[-1][j][1] for j in range(m+1))
# 第几次交易在第三个维度
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        n = len(prices) 
        dp = [[[0 for _ in range(2)] for _ in range(2)] for _ in range(n)] 
        dp[0][0] = [-prices[0], -prices[0]] 
        dp[0][1] = [0, 0]
        for i in range(1, n):
            dp[i][0][0] = max(dp[i-1][0][0], - prices[i]) 
            dp[i][1][0] = max(dp[i-1][1][0], dp[i-1][0][0] + prices[i])
            dp[i][0][1] = max(dp[i-1][0][1], dp[i-1][1][0] - prices[i])
            dp[i][1][1] = max(dp[i-1][1][1], dp[i-1][0][1] + prices[i])
        return max(dp[n-1][1])
  • 初始化可以多种解读。
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        n = len(prices)
        m = 2
        dp = [[[0 for _ in range(2)] for _ in range(m+1)] for _ in range(n)]
        dp[0][0] = [-float('inf'), 0]
        dp[0][1] = [-prices[0], 0]
        dp[0][2] = [-prices[0], 0]
        for i in range(1, n):
            for j in range(1, m+1):
                dp[i][j][0] = max(dp[i-1][j][0], dp[i-1][j-1][1]-prices[i])
                dp[i][j][1] = max(dp[i-1][j][1], dp[i-1][j][0]+prices[i])
        return max([dp[n-1][j][1] for j in range(m+1)])
  • dp[i][j][k]: 第i天,最多j次交易 (j=1,2),状态k 的最大利润
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        n = len(prices)
        k = 2
        dp = [[[0 for _ in range(2)] for _ in range(k+1)] for _ in range(n)] 
        dp[0][0] = [-float('inf'), 0] 
        dp[0][1] = [-prices[0], 0]
        dp[0][2] = [-prices[0], 0]
        for i in range(1, n):
            for j in range(1, k+1):
                dp[i][j][0] = max(dp[i-1][j][0], dp[i-1][j-1][1] - prices[i]) 
                dp[i][j][1] = max(dp[i-1][j][1], dp[i-1][j][0] + prices[i])
        #return max([dp[n-1][j][1] for j in range(1, k+1)])
        return dp[n-1][k][1] 

188. 买卖股票的最佳时机 IV

  • 思路
    • example
    • 最多k笔交易
    • DP, 三维
      • dp[i][j][l]: 第i天,j次交易 (j=1,2),状态l 的最大利润
        • l=0: 持有 (已买入)
        • l=1: 不持有 (已卖出)
        • 注意:先买后卖

j = 1, 2, ..., k:
dp[i][j][0] = max(dp[i-1][j][0], dp[i-1][j-1][1]-prices[i])
dp[i][j][1] = max(dp[i-1][j][1], dp[i-1][j][0]+prices[i])

  • 复杂度. 时间:O(n), 空间: O(n)
class Solution:
    def maxProfit(self, k: int, prices: List[int]) -> int:
        dp = [[[0] * 2 for _ in range(k+1)] for _ in range(len(prices))]
        for j in range(k+1):
            dp[0][j] = [-float('inf'), -float('inf')]
        dp[0][0] = [-float('inf'), 0]
        dp[0][1] = [-prices[0], -float('inf')]
        for i in range(1, len(prices)):
            for j in range(1, k+1):
                dp[i][j][0] = max(dp[i-1][j][0], dp[i-1][j-1][1]-prices[i])
                dp[i][j][1] = max(dp[i-1][j][1], dp[i-1][j][0]+prices[i])
        return max(dp[-1][j][1] for j in range(k+1))
class Solution:
    def maxProfit(self, k: int, prices: List[int]) -> int:
        n = len(prices)
        m = k
        dp = [[[0 for _ in range(2)] for _ in range(m+1)] for _ in range(n)]
        dp[0][0] = [-float('inf'), 0]
        for j in range(1, m+1):
            dp[0][j] = [-prices[0], 0]
        for i in range(1, n):
            for j in range(1, m+1):
                dp[i][j][0] = max(dp[i-1][j][0], dp[i-1][j-1][1]-prices[i])
                dp[i][j][1] = max(dp[i-1][j][1], dp[i-1][j][0]+prices[i])
        return max([dp[n-1][j][1] for j in range(m+1)])
class Solution:
    def maxProfit(self, k: int, prices: List[int]) -> int:
        n = len(prices) 
        dp = [[[0 for _ in range(2)] for _ in range(k+1)] for _ in range(n)] 
        dp[0][0] = [-float('inf'), 0] 
        for j in range(1, k+1):
            dp[0][j] = [-prices[0], 0] 
        for i in range(1, n):
            for j in range(1, k+1):
                dp[i][j][0] = max(dp[i-1][j][0], dp[i-1][j-1][1]-prices[i])
                dp[i][j][1] = max(dp[i-1][j][1], dp[i-1][j][0]+prices[i]) 
        return dp[n-1][k][1] 
class Solution:
    def maxProfit(self, k: int, prices: List[int]) -> int:
        n = len(prices)  
        dp = [[[0 for _ in range(2)] for _ in range(k+1)] for _ in range(n)] 
        dp[0][0] = [0, 0] 
        for j in range(1, k+1):
            dp[0][j] = [-prices[0], 0]
        for i in range(1, n):
            for j in range(1, k+1):
                dp[i][j][0] = max(dp[i-1][j][0], dp[i-1][j-1][1] - prices[i])
                dp[i][j][1] = max(dp[i-1][j][1], dp[i-1][j][0] + prices[i]) 
        return dp[n-1][k][1]
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容