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

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

这一题较难,难点是状态比较多,需要考虑两笔交易,则共5个状态需要被记录,用当前是否持有股票来划分子集进行计算

class Solution {
    public int maxProfit(int[] prices) {
        // 由于此题可以完成两笔交易,因此不只是只有一次持有和不持有,有两次,即四个状态+未交易过共5种状态
        // 因此一天可以有五种状态子集,f[i][0~4],0表示未交易过,1表示第一次持有2表示第一次不持有...
        // f[i][0]=f[i-1][0] ,直接转移即可,没有操作
        // f[i][1]=max(f[i-1][1],f[i-1][0]-prices[i])
        // f[i][2]=max(f[i-1][2],f[i-1][1]+prices[i])
        // f[i][3]=max(f[i-1][3],f[i-1][2]-prices[i])
        // f[i][4]=max(f[i-1][4],f[i-1][3]+prices[i])
        int[][] f=new int[prices.length+1][5];
        f[1][0]=0;
        f[1][1]=-prices[0];
        f[1][2]=0;
        f[1][3]=-prices[0];
        f[1][4]=0;
        for(int i=2;i<=prices.length;i++)
        {
            f[i][0]=f[i-1][0];
            f[i][1]=Math.max(f[i-1][1],f[i-1][0]-prices[i-1]);
            f[i][2]=Math.max(f[i-1][2],f[i-1][1]+prices[i-1]);
            f[i][3]=Math.max(f[i-1][3],f[i-1][2]-prices[i-1]);
            f[i][4]=Math.max(f[i-1][4],f[i-1][3]+prices[i-1]);
        }
        return f[prices.length][4];   //最终状态是这个表达式,实际可能第一次卖出就达到最大值了,即f[prices.length][2],但是f[prices.length][4]是最大的集合,是包含f[prices.length]
        // 用更加通俗的道理:即第一次卖出达到最大了,可以再买,再买一次,也是最大值
    }   
}

最后的返回值,如同官方题解说的这样

 

posted @ 2024-09-06 01:53  风乐  阅读(13)  评论(0)    收藏  举报