【LeetCode】最佳买卖股票时机含冷冻期 [M](动态规划)

166 篇文章 0 订阅

309. 最佳买卖股票时机含冷冻期 - 力扣(LeetCode)

一、题目

给定一个整数数组prices,其中第  prices[i] 表示第 i 天的股票价格 。​

设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):

卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

示例 1:
输入: prices = [1,2,3,0,2]
输出: 3 
解释: 对应的交易状态为: [买入, 卖出, 冷冻期, 买入, 卖出]

示例 2:
输入: prices = [1]
输出: 0

提示:

  • 1 <= prices.length <= 5000
  • 0 <= prices[i] <= 1000

二、代码

class Solution {
    public int maxProfit(int[] prices) {
        // 如果只有一个数,那么最大的收益肯定就是0
        if (prices == null || prices.length < 2) {
            return 0;
        }
        
        int n = prices.length;
        // buy[i]指的是在0到i的范围上,最后一次操作一定是买操作能拿到的最大收益。
        int[] buy = new int[n];
        // sell[i]指的是0~i做无限制次数的交易,最后一个动作必须是卖,能获得的最好收入。
        int[] sell = new int[n];
        // i=0的时候,我们在0~0选择一个买入时间,只有一个时间点0,所以只能选0时间点买入,但是0之前已经没有别的时间点了,也就是说在0买入时间之前的最大收益就是0,所以buy[0] = 0 -prices[0]
        buy[0] = -prices[0];
        // 取两种情况的最大值
        // 情况1:1不参与交易,buy[1] = buy[0]
        // 情况2:1参与交易,buy[1] = 0 - prices[1]
        buy[1] = Math.max(buy[0], -prices[1]);
        // 如果0位置是卖出操作,前面必须要有买入操作才可以,但是0前面已经没有时间点了,不可能有买入操作,所以sell[0]这个情况本身就是不存在的,直接设置为0。
        sell[0] = 0;
        // 取两种情况的最大值
        // 情况1:1不参与交易,sell[1] = sell[0]
        // 情况2:1参与交易,sell[1] = buy[0] + prices[1]
        sell[1] = Math.max(sell[0], buy[0] + prices[1]);
        // 开始构造buy和sell
        for (int i = 2; i < n; i++) {
            // 取两种情况的最大值    因为卖操作之后需要冻结一天才可以再买,所以这里用sell[i - 2]
            buy[i] = Math.max(buy[i - 1], sell[i - 2] - prices[i]);
            // 取两种情况的最大值
            // 我们能发现sell是依赖buy求出来的    买操作之后并不需要冻结一天,所以这里用buy[i - 1]
            sell[i] = Math.max(sell[i - 1], buy[i - 1] + prices[i]);
        }

        // 最后的结果就是0~n-1位置去进行交易,并且保证最后一次操作一定是卖的情况下的最高收益
        return sell[n - 1];
    }
}

三、解题思路 

这道题优化的关键就是引入了buy数组和sell数组。

buy[i]:指的是在0到i的范围上,最后一次操作一定是买操作能拿到的最大收益。这个买操作的时间点并不一定是i,可以是0~i上的任意时间点。buy[i]的值就会在0~i范围上选择一个最后买入的时间点,能够使i之前的最大收益减去i买入的价格得到的结果最大,这个最大值就是buy[i]。

sell数组的思路和buy数组就基本差不多了。sell[i]:0~i做无限制次数的交易,最后一个动作必须是卖,能获得的最好收入。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值