题解 | #买卖股票的最好时机(三)#

买卖股票的最好时机(三)

https://www.nowcoder.com/practice/4892d3ff304a4880b7a89ba01f48daf9

多个整体状态的DP数组应该保存什么?

  • 此题跟打家劫舍(二)的环形房屋都有多状态,环形房屋有两种情况的状态,一个是只选第一个房子不选最后一个房子,一个是只选最后一个房子不选最后一个房子,最后比较这两种状态的DP数组的最大值。
  • 由于本题最多只能进行两次股票买卖,因此需要分多个整体状态来分析最大收益值,因此需要一个二维dp数组dp[i][j],表示第i天股票状态为j的收益,这跟前一天的股票状态有关。一共有五种状态:
  • 0表示到第i天为止都从未买过股票的收益,
  • 1表示到第i天为止买过一次股票但是没有卖出的收益,
  • 2表示到第i天为止买过一次股票也卖过一次的收益,
  • 3表示到第i天为止买过两次股票但只卖出一次的收益,
  • 4表示到第i天为止买过两次股票并且卖出两次的收益。
  • 由于股票整体状态中可能是进行一次股票买卖的收益最高,也有可能是进行两次股票买卖的收益最高,因此要在这两种情况中选最大收益。

最小子问题

  • 第1天没有买入股票,收益为dp[0][0] = 0
  • 第1天买入股票,收益为dp[0][1] = -prices[0]

如何思考状态转移方程?

股票当天状态的收益跟前一天的状态收益有关:

  • 如果当天状态为0,说明至今都没有持有股票,收益为dp[i][0] = dp[i-1][0]
  • 如果当天状态为1,说明至今买入过一次股票,则有可能是在今天之前买的,也有可能是在今天买的,取这两种情况的最大值,收益为dp[i][1] = max(dp[i-1][1], dp[i-1][0]-prices[i]
  • 如果当天状态为2,说明至今买过和卖出一次股票,则有可能在今天之前就买卖过一次股票了,也有可能在今天才第一次卖出股票,取这两种情况的最大值,收益为dp[i][2] = max(dp[i-1][2], dp[i-1][1]+prices[i]
  • 如果当天状态为3,说明至今买过两次股票和卖过一次股票,则有可能是在今天之前就买过两次股票和卖出一次股票了,也有可能在今天才买入第二次股票,取这两种情况的最大值,收益为dp[i][3] = max(dp[i-1][3], dp[i-1][2]-prices[i]
  • 如果当天状态为4,说明至今买过两次股票和卖出两次股票,则有可能是在今天之前就买卖过两次股票了,也有可能是在今天才卖出第二次股票,取这两种情况最大值,收益为dp[i][4] = max(dp[i-1][4], dp[i-1][3]+prices[i]
  • 最后dp[prices.length-1]表示最终买卖一次股票的收益,dp[prices.length-1]表示最终买卖两次股票的收益
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 * 两次交易所能获得的最大收益
 * @param prices int整型一维数组 股票每一天的价格
 * @return int整型
 */
function maxProfit( prices ) {
    // write code here
    // 0表示第i天都从未买过股票的收益,
    // 1表示第i天买过一次股票但是没有卖出的收益,
    // 2表示第i天买过一次股票也卖过一次的收益,
    // 3表示第i天买过两次股票但只卖出一次的收益,
    // 4表示第i天买过两次股票并且卖出两次的收益。
    // 因为可能有负收益,所以要初始化为最小值。
    const dp = Array.from(new Array(prices.length), () => new Array(5).fill(-Infinity));  
    dp[0][0] = 0;  // 第一天不买入的收益
    dp[0][1] = -prices[0];  // 第一天买入的收益

    for (let i = 1; i < prices.length; ++i) {
        dp[i][0] = dp[i-1][0];  // 都是0,但是初始为-Infinity所以要更新
        dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0]-prices[i]);
        dp[i][2] = Math.max(dp[i-1][2], dp[i-1][1]+prices[i]);
        dp[i][3] = Math.max(dp[i-1][3], dp[i-1][2]-prices[i]);
        dp[i][4] = Math.max(dp[i-1][4], dp[i-1][3]+prices[i]);
    }

    return Math.max(dp[prices.length-1][2], dp[prices.length-1][4]);
}
module.exports = {
    maxProfit : maxProfit
};

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务