Best Time to Buy and Sell Stock with Cooldown

Posted 太空工程车

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Best Time to Buy and Sell Stock with Cooldown相关的知识,希望对你有一定的参考价值。

题目:

给定一个数组nums,nums[i]代表的是在第i天的股价
  例如:[1,2,3,0,10,4],数组代表的含义是:有6天的股价给你了,从第一天到第六天的股价分别是 1,2,3,0,10,4
  你买卖股票的次数不限,但是有两个限制:

    1. 卖不能在买前面(不能买10,卖0)
    2. 一次交易完成之后,至少休息一天才能继续买入(买1,卖3之后,不能立刻买0,必须至少等一天)

问题:求出最大的获利数(对于例子来说,max=11,买1卖2,休息一天,买0卖10)


 

思路:
用dp来解。dp就一定要有状态和状态转换方程。

在每一天,都有3种状态:

  1.   buy
  2.   sell
  3.   rest

那么我们就可以根据给定的数组,新建三个状态数组,代表每天对应的状态。
buy[n], sell[n], rest[n](n代表给定数组的长度)
那么状态就有了表示方法:
buy[i]:在第i天之前,以buy为结束的任何交易组合的最大利润
sell[i]:在第i天之前,以sell为结束的任何交易组合的最大利润
rest[i]:在第i天之前,以rest为结束的任何交易组合的最大利润
状态转换方程:(price是当前日期的股价)

  buy[i] = max(rest[i-1] - price, buy[i-1]) 
  sell[i] = max(buy[i-1] + price, sell[i-1])
  rest[i] = max(sell[i-1], buy[i-1], rest[i-1])

以上的状态转换方程只是把题目的要求和之前的分析总结起来,例如:buy[i] = 今天买入(必须在休息之后才能买入) 或者 之前就有买入,保持不卖出
还有一个隐藏的要素:
  rest[i] = sell[i-1] 这个等式的意义在于,如果在今天休息,那么这天的收益就跟前一天sell相同
那么把这个等式代入,就有:

    buy[i] = max(sell[i-2] - price, buy[i-1])
    sell[i] = max(buy[i-1] + price, sell[i-1])

很好理解,如果要在这一天卖的话,至少要在前两天把之前的股票卖掉(因为间隔为1天)

在这之后,还可以更进一步优化,这里我们可以发现第i天的状态和第i-1天和第i-2天的状态有关,那么就可以不用状态数组,用两个变量来保存i-1和i-2的数据


 

代码:

 1     public int maxProfit(int[] prices) {
 2         int sell = 0, prevSell = 0, buy = Integer.MIN_VALUE, prevBuy;
 3         for (int price : prices) {
 4             prevBuy = buy;
 5             buy = Math.max(prevSell - price, prevBuy); //这里buy和sell的赋值顺序不能变,因为prevSell在这里相当于方程中的sell[i-2]
 6             prevSell = sell; //到这里,prevSell就真正变成了sell[i-1],变成了真正的previous sell
 7             sell = Math.max(prevBuy + price, prevSell);
 8         }
10         return sell;
11     }

 

以上是关于Best Time to Buy and Sell Stock with Cooldown的主要内容,如果未能解决你的问题,请参考以下文章

最强解析面试题:best-time-to-buy-and-sell-stock

最强解析面试题:best-time-to-buy-and-sell-stock

121. Best Time to Buy and Sell Stock

122. Best Time to Buy and Sell Stock II

123. Best Time to Buy and Sell Stock III***

LeetCode 121. Best Time to Buy and Sell Stock