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)
prices = [1, 2, 3, 0, 2]
maxProfit = 3
transactions = [buy, sell, cooldown, buy, sell]
思路:用buy[i] 来表示准备买入第i天的股票之前(还没有买入第i天的股票)的当前的最大的利润值,sell[i]表示卖了第i天的股票之后当前的最大利润值。
如果准备要买入第i天的股票,因为要冷却一天,那么第i-1天的股票是不能卖的,buy[i] 就是buy[i-1] ,buy[i-2] ,sell[i-2] 中的最大的一个
buy[i] = max{buy[i-1] , buy[i-2] , sell[i-2] }
sell[i]表示要卖掉第i天的股票之后的当前的利润的最大值,那么怎么计算sell[i]呢,第i天要卖掉股票,对应于前面哪一次的买入会使得sell[i]最大呢,要记录下第0到i-1天中买入哪一天的股票之后还剩下的利润最大的数maxAfterBuy,maxAfterBuy=max{buy[j]-prices[j]} ,其中0<= j <=i ,
那么sell[i]=maxAfterBuy+prices[i];
对于从0到第i天的最大利益就应该为res=max{buy[i] , sell[i] }
在遍历数组的过程中记录下最大的 res的即可。
public class Solution {
public int maxProfit(int[] prices) {
int res=0;
int n=prices.length;
if(n<2) return 0;
if(n==2) return prices[1]-prices[0] > res ? prices[1]-prices[0] : res;
int[] buy=new int[n];
int[] sell=new int[n];
buy[0]=0;
sell[0]=0;
buy[1]=0;
sell[1]=prices[1]-prices[0];
res = res > sell[1] ? res : sell[1];
int maxAfterBuy=buy[1]-prices[1] > buy[0]-prices[0] ? buy[1]-prices[1] : buy[0]-prices[0];
for(int i=2;i<n;i++)
{
buy[i]=Math.max(buy[i-1],Math.max(buy[i-2],sell[i-2]));
sell[i]=prices[i]+maxAfterBuy;
if(maxAfterBuy < buy[i]-prices[i])
{
maxAfterBuy=buy[i]-prices[i];
}
if(res<Math.max(buy[i],sell[i]))
res=Math.max(buy[i],sell[i]);
}
return res;
}
}