LeetCode | 0714. Best Time to Buy and Sell Stock with Transaction Fee買賣股票的最佳時機含手續費【Python】

LeetCode 0714. Best Time to Buy and Sell Stock with Transaction Fee買賣股票的最佳時機含手續費【Medium】【Python】【動態規劃】

Problem

LeetCode

Your are given an array of integers prices, for which the i-th element is the price of a given stock on day i; and a non-negative integer fee representing a transaction fee.

You may complete as many transactions as you like, but you need to pay the transaction fee for each transaction. You may not buy more than 1 share of a stock at a time (ie. you must sell the stock share before you buy again.)

Return the maximum profit you can make.

Example 1:

Input: prices = [1, 3, 2, 8, 4, 9], fee = 2
Output: 8
Explanation: The maximum profit can be achieved by:
Buying at prices[0] = 1Selling at prices[3] = 8Buying at prices[4] = 4Selling at prices[5] = 9The total profit is ((8 - 1) - 2) + ((9 - 4) - 2) = 8.

Note:

0 < prices.length <= 50000.

0 < prices[i] < 50000.

0 <= fee < 50000.

問題

力扣

給定一個整數數組 prices,其中第 i 個元素代表了第 i 天的股票價格 ;非負整數 fee 代表了交易股票的手續費用。

你可以無限次地完成交易,但是你每次交易都需要付手續費。如果你已經購買了一個股票,在賣出它之前你就不能再繼續購買股票了。

返回獲得利潤的最大值。

示例 1:

輸入: prices = [1, 3, 2, 8, 4, 9], fee = 2
輸出: 8
解釋: 能夠達到的最大利潤:  
在此處買入 prices[0] = 1
在此處賣出 prices[3] = 8
在此處買入 prices[4] = 4
在此處賣出 prices[5] = 9
總利潤: ((8 - 1) - 2) + ((9 - 4) - 2) = 8.

注意:

  • 0 < prices.length <= 50000.
  • 0 < prices[i] < 50000.
  • 0 <= fee < 50000.

思路

動態規劃

相當于在 LeetCode 0122 基礎上加了手續費。

找到狀態方程

dp[i][k][0] = max(dp[i-1][k][0], dp[i-1][k][1] + prices[i] - fee)
解釋:昨天沒有股票,昨天有股票今天賣出,同時減去交易費用(交易費用記在買或賣都可以)

dp[i][k][1] = max(dp[i-1][k][1], dp[i-1][k][0] - prices[i])
解釋:昨天有股票,昨天沒有股票今天買入

base case:
dp[-1][k][0] = dp[i][k][0] = 0
dp[-1][k][1] = dp[i][k][1] = -inf

k = +inf
因為 k 為正無窮,那么可以把 k 和 k-1 看成是一樣的。
buy+sell = 一次完整的交易,這里把 sell 看成一次交易,所以第一行是 k-1。
dp[i][k][0] = max(dp[i-1][k][0], dp[i-1][k-1][1] + prices[i] - fee)
            = max(dp[i-1][k][0], dp[i-1][k][1] + prices[i] - fee)
dp[i][k][1] = max(dp[i-1][k][1], dp[i-1][k][0] - prices[i])

所以 k 對狀態轉移沒有影響:
dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i] - fee)
dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i])

i = 0 時,dp[i-1] 不合法。
dp[0][0] = max(dp[-1][0], dp[-1][1] + prices[i] - fee)
         = max(0, -infinity + prices[i] - fee)
         = 0
dp[0][1] = max(dp[-1][1], dp[-1][0] - prices[i])
         = max(-infinity, 0 - prices[i]) 
         = -prices[i]

空間復雜度: O(1)

Python3代碼
class Solution:
    def maxProfit(self, prices: List[int], fee: int) -> int:
        dp_i_0 = 0
        dp_i_1 = float('-inf')  # 負無窮
        for i in range(len(prices)):
            temp = dp_i_0
            # 昨天沒有股票,昨天有股票今天賣出,同時減去交易費用
            dp_i_0 = max(dp_i_0, dp_i_1 + prices[i] - fee)  # dp_i_0 和 dp_i_1 可以看成是變量,存儲的都是上一次即昨天的值
            # 昨天有股票,昨天沒有股票今天買入
            dp_i_1 = max(dp_i_1, temp - prices[i])
        return dp_i_0   

代碼地址

GitHub鏈接

參考

一個方法團滅 6 道股票問題

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容