LeetCode 122、买卖股票的最佳时机 II

93 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第14天,点击查看活动详情

题目:给定一个数组prices,其中prices[i]表示的是第i天股票的价格,现规定股票在每天都可以进行购买或者出售,但每天最多只能持有一股股票,返回可获得的最大利润。

解题思路

本题和之前的股票那题有点类似,区别是本题可多次买入,因此可以多次计算利润。最先想到的解题方法是贪心,我们可以在每次买入股票的时候都选一个低价时期买入,在高价时期卖出,即假设我们在第一天买入,在第三天卖出,那么利润即为dp[3]-dp[1],假设期间的价格为1, 3, 5,那最终的利润即等于5-1 = 5-3+3-1,如果期间价格为1, 8, 5,那我们只需忽略利润为负的那次即可,因此根据贪心可得:

public int maxProfit(int[] prices) {
    int max = 0;
    for(int i=1;i<prices.length;i++){
        max += prices[i]>prices[i-1]?prices[i]-prices[i-1]:0;
    }
    return max;
}

和之前那题一样,本题也可使用动态规划来解决,基本思路为:在每天,我们都只有两个状态,即买入股票和不买股票,我们可以使用两个数组分别记录每天的状态,这里使用dp[len][2]来表示,其中dp[i][0]表示当天买入股票,而dp[i][1]则为当天不买入股票,如果当天买入,则其最大利润为max(上一天买入股票的利润,上一天没有买入股票-当前股票价格):

dp[i][0]=max(dp[i1][0],dp[i1][1]prices[i])dp[i][0] = max(dp[i-1][0], dp[i-1][1]-prices[i])

同样,当天不买入股票的最大利润为max(前一天买入股票的利润最大值+当天股票价格,前一天不买入股票最大利润):

dp[i][1]=max(dp[i1][1],dp[i1][0]+prices[i])dp[i][1] = max(dp[i-1][1], dp[i-1][0]+prices[i])

可得代码如下:

public int maxProfit(int[] prices) {
    if(prices.length<2) return 0;
    int[][] dp = new int[prices.length][2];
    dp[0][0] = -prices[0]; // 当天持有股票
    dp[0][1] = 0;// 当天不持有股票
    for(int i=1;i<prices.length;i++){
        // 当天持有 = max(上一天不持有-prices,上一天持有)
        dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1]-prices[i]);
        // 当天不持有 = max(上一天不持有,上一天持有+price)
        dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0]+prices[i]);
    }
    return dp[prices.length-1][1];
}