1. 程式人生 > 其它 >【Leetcode】123. Best Time to Buy and Sell Stock III

【Leetcode】123. Best Time to Buy and Sell Stock III

技術標籤:LC 貪心、動態規劃與記憶化搜尋leetcode動態規劃演算法

題目地址:

https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/

給定一個股票的價格,以長 n n n的陣列 p p p的形式給出。規定每天只能做一次交易,並且每次只能買 1 1 1股,問如果只允許做最多 2 2 2次買賣,那麼最大收益是多少。

思路是前後綴分解。首先預處理出給定字首 p [ 0 : k ] p[0:k] p[0:k]且只進行一次交易的情況下的最大收益,這個可以用動態規劃做。設 f [ k ] f[k] f[k]是上述字首的最大收益,那麼 f [ 0 ] = 0 f[0]=0

f[0]=0 f [ k ] = max ⁡ { f [ k − 1 ] , p [ k ] − m } , k ≥ 1 f[k]=\max\{f[k-1],p[k]-m\},k\ge 1 f[k]=max{f[k1],p[k]m},k1 m = min ⁡ p [ 0 : k − 1 ] m=\min p[0:k-1] m=minp[0:k1]。算出 f f f之後,可以列舉第二次交易的買入點。設第二次交易的買入點是 u u u,那麼總的最大收益是 ( M − p [ u ] ) + f [ u ] (M-p[u])+f[u] (Mp[u])+f[u],其中 M = max ⁡ p [ u + 1 : n − 1 ] M=\max p[u+1:n-1]
M=maxp[u+1:n1]
。這裡注意,當第一次賣出點和第二次買入點重合的時候,我們實際上也同時枚舉了只交易一次的情況。所以必須得寫 ( M − p [ u ] ) + f [ u ] (M-p[u])+f[u] (Mp[u])+f[u]而不能寫 ( M − p [ u ] ) + f [ u − 1 ] (M-p[u])+f[u-1] (Mp[u])+f[u1]。程式碼如下:

public class Solution {
    public int maxProfit(int[] prices) {
        if (prices == null || prices.length <=
1) { return 0; } int n = prices.length; int[] dp = new int[n]; for (int i = 1, min = prices[0]; i < n; i++) { dp[i] = Math.max(dp[i - 1], prices[i] - min); min = Math.min(min, prices[i]); } int res = 0; for (int i = n - 1, max = 0; i >= 0; i--) { res = Math.max(res, max - prices[i] + dp[i]); max = Math.max(max, prices[i]); } return res; } }

時空複雜度 O ( n ) O(n) O(n)