【leetcode笔记】Python实现 309. Best Time to Buy and Sell Stock with Cooldown

题目描述

Say you have an array for which the ith element is the price of a given stock on day i.

Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times) with the following restrictions:

You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).

After you sell your stock, you cannot buy stock on next day. (ie, cooldown 1 day)

Example:

Input: [1,2,3,0,2]
Output: 3
Explanation: transactions = [buy, sell, cooldown, buy, sell]

题目大意

给出一系列的股票交易价格,股票交易的原则是必须先买然后再卖,在买入之前必须至少休息一天。求最后能得到的最大收益。

解题方法

动态规划

这个题和【leetcode笔记】Python实现 714. Best Time to Buy and Sell Stock with Transaction Fee比较像。做题方法都是使用了两个数组:

cash[i] 该天结束手里没有股票的情况下,已经获得的最大收益
hold[i] 该天结束手里有股票的情况下,已经获得的最大收益

状态转移方程:

对于cash[i],最大利润有两种可能,一是今天没动作跟昨天未持股状态一样,二是今天卖了股票,所以状态转移方程如下:

max(昨天手里没有股票的收益,昨天手里有股票的收益+今天卖股票的收益)

cash[i] = max(cash[i - 1], hold[i - 1] + prices[i])

对于hold[i],最大利润有两种可能,一是今天没动作跟昨天持股状态一样,二是前天卖了股票,今天买了股票,因为 cooldown 只能隔天交易,所以今天买股票要追溯到前天的状态。状态转移方程如下:

max(昨天手里有股票的收益,前天卖掉股票的收益 - 今天股票的价格)。

hold[i] = max(hold[i - 1], cash[i - 2] - prices[i])

最终我们要求的结果是cash[n - 1],表示最后一天结束时,手里没有股票时的最大利润。

这个算法的空间复杂度是O(n),不过由于cash[i]仅仅依赖前一项,hold[i]仅仅依赖前两项,所以可以优化到O(1),具体见第二种代码实现。

代码如下:

时间复杂度是O(n),空间复杂度是O(n)

class Solution:
    def maxProfit(self, prices):
        """
        :type prices: List[int]
        :rtype: int
        """
        if not prices: return 0
        cash = [0] * len(prices)
        hold = [0] * len(prices)
        hold[0] = -prices[0]
        for i in range(1, len(prices)):
            cash[i] = max(cash[i - 1], hold[i - 1] + prices[i])
            hold[i] = max(hold[i - 1], (cash[i - 2] if i >= 2 else 0) - prices[i])
        return cash[-1]

空间复杂度O(1)

class Solution:
    def maxProfit(self, prices):
        """
        :type prices: List[int]
        :rtype: int
        """
        if not prices: return 0
        prev_cash = 0
        curr_cash = 0
        hold = -prices[0]
        for i in range(1, len(prices)):
            temp = curr_cash
            curr_cash = max(curr_cash, hold + prices[i])
            hold = max(hold, (prev_cash if i >= 2 else 0) - prices[i])
            prev_cash = temp
        return curr_cash

转自:https://blog.csdn.net/fuxuemingzhu/article/details/82656899
参考:https://soulmachine.gitbooks.io/algorithm-essentials/java/dp/best-time-to-buy-and-sell-stock-with-cooldown.html

你可能感兴趣的:(leetcode,Python刷Leetcode)