【LeetCode】解题309:Best Time to Buy and Sell Stock with Cooldown(动态规划)

LeetCode解题 309:Best Time to Buy and Sell Stock with Cooldown (动态规划)

Problem 309: Best Time to Buy and Sell Stock with Cooldown [Medium]

Say you have an array for which the ith element is the price of a given stock on day i.

Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times) with the following restrictions:

  • You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
  • After you sell your stock, you cannot buy stock on next day. (ie, cooldown 1 day)

Example:

Input: [1,2,3,0,2]
Output: 3
Explanation: transactions = [buy, sell, cooldown, buy, sell]

来源:LeetCode

解题思路

本题仍然需要使用动态规划思想。与题解188:Best Time to Buy and Sell Stock IV同属于最佳时机买卖股票问题。

解题思路与之前不同的是,不再使用minCost和maxP的思路,而是直接使用maxP的状态转移方程,每天的maxP分为两种:maxP0和maxP1,分别代表当天不持有股票和当天持有股票的最大利润。本题中在买操作之前有一个冷却期,因此第i天的maxP0可以由第i-1天的maxP0和maxP1转移,而第i天的maxP1则由第i-1天的maxP1和第i-2天的maxP0转移。这是由于第i天买入股票的前提条件是在第i-2天之前已经卖出,而不能在i-1天才卖出,所以无法由第i-1天的maxP0转移至第i天的maxP1

状态转移方程为:
m a x P 0 [ i ] = max ⁡ { m a x P 0 [ i − 1 ] , m a x P 1 [ i − 1 ] + p r i c e s [ i ] } m a x P 1 [ i ] = max ⁡ { m a x P 1 [ i − 1 ] , m a x P 0 [ i − 2 ] − p r i c e s [ i ] } maxP_0[i] = \max\{maxP_0[i-1], maxP_1[i-1] + prices[i]\} \\ maxP_1[i] = \max\{maxP_1[i-1], maxP_0[i-2] - prices[i]\} maxP0[i]=max{maxP0[i1],maxP1[i1]+prices[i]}maxP1[i]=max{maxP1[i1],maxP0[i2]prices[i]}
其中, m a x P 1 [ i − 1 ] + p r i c e s [ i ] maxP_1[i-1] + prices[i] maxP1[i1]+prices[i]的意思是第i-1天持有的股票在当前天卖出; m a x P 0 [ i − 2 ] − p r i c e s [ i ] maxP_0[i-2] - prices[i] maxP0[i2]prices[i]的意思是第i-2天之前卖出的股票在当前天买入。

由于maxP0更新只使用到前一天的maxP0和maxP1,maxP1更新也只使用到前一天的maxP1和再前一天的maxP0,因此可以不使用maxP0[N]和maxP1[N]来存储,只需使用常数空间。
状态转移更新为:
m a x P 0 = max ⁡ { m a x P 0 , m a x P 1 + p r i c e s [ i ] } m a x P 1 = max ⁡ { m a x P 1 , p r e m a x P 0 − p r i c e s [ i ] } maxP_0 = \max\{maxP_0, maxP_1 + prices[i]\} \\ maxP_1 = \max\{maxP_1, premaxP_0 - prices[i]\} maxP0=max{maxP0,maxP1+prices[i]}maxP1=max{maxP1,premaxP0prices[i]}
其中, m a x P 0 maxP_0 maxP0初始化为0, m a x P 1 maxP_1 maxP1初始化为-prices[0], p r e m a x P 0 premaxP_0 premaxP0指i-2天的 m a x P 0 maxP_0 maxP0

该方法时间复杂度为 O ( n ) O(n) O(n),空间复杂度为 O ( 1 ) O(1) O(1)

运行结果:
在这里插入图片描述
要点:动态规划

Solution (Java)

class Solution {
    public int maxProfit(int[] prices) {
        int N = prices.length;
        if(N < 2) return 0;
        int minCost = prices[0];
        int[] maxP = new int[N];
        int maxP0 = 0;
        int maxP1 = -prices[0];
        int pre_maxP0 = 0;
        int temp;
        for(int i = 1; i < N; i++){
            temp = maxP0;
            maxP0 = Math.max(maxP0, maxP1 + prices[i]);
            maxP1 = Math.max(maxP1, pre_maxP0 - prices[i]);
            pre_maxP0 = temp;
        }
        return maxP0;
    }
}

修改过程

  • 一开始pre_maxP0采样先进先出队列,但是提交后发现运行时间需要2ms,后修改为两个变量temp和pre_maxP0。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值