Leet123. 買賣股票的最佳時機 III(Best Time to Buy and Sell Stock III)

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

public int maxProfit(int[] prices) 
    {
        if(prices.length==0)
        {
            return 0;
        }
        int left[]=new int[prices.length];
        int right[]=new int[prices.length];
        left[0]=0;
        right[prices.length-1]=0;
        int leftmin=prices[0];//記錄左邊的最小值
        for(int i=1;i<prices.length;i++)
        {
            if(prices[i]>prices[i-1])
            {
                left[i]=Math.max(prices[i]-leftmin, left[i-1]);
            }
            else
            {
                left[i]=left[i-1];
                leftmin=Math.min(leftmin, prices[i]);
            }
        }
        //右
        right[prices.length-1]=0;
        int rightmax=prices[prices.length-1];//記錄右邊最大值
        for(int i=prices.length-2;i>=0;i--)
        {
            if(prices[i+1]>prices[i])
            {
                right[i]=Math.max(rightmax-prices[i], right[i+1]);
            }
            else
            {
                right[i]=right[i+1];
                rightmax=Math.max(prices[i], rightmax);
            }
        }
        int res=0;
        for(int i=0;i<prices.length-1;i++)
        {
            if(left[i]+right[i]>res)
            {
                res=left[i]+right[i];
            }
        }
        return res;
    }

思路:

與該系列前兩題不同   本題要求最多進行“兩次”交易

利用動態規劃處理

首先最多進行兩次交易 可以將prices分爲兩部分 左邊代表一次交易 右邊代表第二次交易 而分割的位置是不確定的

但無論分割的位置是哪一處  左邊、右邊都將成爲唯一的   那麼只需要計算在每一種分割的情況下  左、右收益之和最大的是哪一種分割就可以了

用題目給出的[3,3,5,0,0,3,1,4]這組數據來還原一下計算步驟

用數組left[]表示左邊的“最大收益”

用數組right[]表示右邊的“最大收益”

用leftmin表示“目前左邊的最低價格”  用rightmax表示“目前右邊的最高價格”  爲什麼這樣下面會解釋

從left數組的計算開始

對於題目中的  3,3,5,0,0,3,1,4

將leftmin設初值爲3  表示第一天買入

之後對題目數據進行遍歷

從第二天開始(第一天無論是否買入,都不能賣出,所以沒有收益,這時候同時設定left[0]爲0)

第二天的價格爲3,這個價格並沒有高於上一天 (即第一天)的價格

那麼此時left[1]  即第二天的最大收益也爲0

然後對比第二天的價格與leftmin 相同 那麼leftmin保持不變 爲3

之後第三天

第三天時價格爲5,高於上一天(即第二天)的價格3,若賣出 則收益2 將收益2與之前的最大收益left[1]對比 大於left[1]的0

所以將left[2]設置爲2

這裏解釋一下:此時假定的日期分割爲前三天進行第一次交易 後面進行第二次交易

而前三天中的收益分別爲0  0  2  意味着 若分割在第一天 則不能買入賣出 收益爲0 若分割在第二天 價格爲3 3 收益仍爲0 分割在第三天 則就是剛纔的計算結果  所以left[i]表示的是前i天可以獲得的最大收入

接下來繼續推進日期

第四天時價格爲0 收益仍保持前三天的最大值2  但是此時價格0低於目前的“最低價格” 故將最低價格改爲0

第五天不變 略過

第六天時價格爲3 此時由於最低價格爲0 那麼最大收益變爲3

按照這樣的推理方式結束時

對應日期價格 3,3,5,0,0,3,1,4的

左邊最大收益 0,0,2,2,2,3,3,3

用同樣的思維方式對右邊進行推理 來獲得right[]數組 不過由於方式是從右往左 

所以需要略作修改 因爲從左往右時的默認順序是買入-賣出 而從右往左是先賣出再買入

這也就是爲什麼leftmin表示“目前左邊的最低價格”  用rightmax表示“目前右邊的最高價格”

結束時right數組爲4,4,4,4,4,3,3,0

left爲:                 0,0,2,2,2,3,3,3

之後只需要看哪一組left和right之和最大即可

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章