[Leetcode] Best Time to Buy and Sell Stock I,II,III,IV
三种股票交易算法
一、交易次数没有限制
使用贪心策略,找最长递增序列,同时累加相应利润。
二、只有一次交易
使用动态规划算法,从前往后,依次记记录相应时间节点前面的最小price,同时获得在这个节点的最大利润,同时更新最小price
三、最多两次
使用两次动态规划
1、从左向右,记录在相应的时间节点卖出的最大利润,实际上就是问题二
2、从右向左,记录在相应的时间节点买入的最大利润,因此这里需要记录最大的price。
将each 的left[index]+ right[index]曲最大值。
四、是第三个问题的推广,最多进行交易的次数为k,而不是2。
在[1]当中介绍了动态规划转移函数设计的思路,我们需要维护两个变量,local(i,j)和global(i,j)
local(i,j)表示前i天进行j次交易所获得的最大利润,并且最后一天要进行交易
global(i,j)表示前i天进行j次交易所获得的最大交易,最后一天是否进行交易没有限制。
为什么会出现local,主要是为了防止相邻交易的融合,从而造成交易次数的减少,在[1]当中有非常详细的解释。
转移方程具体如下
local(i,j) = max(global(i-1,j-1)+max(diff,0),local(i-1,j)+diff);
global(i,j) = max(global(i-1,j),local(i,j));
如何解释上面的转义方程呢:
可以从第i-1天有没有进行交易来对这个问题进行分类
一、如果第i-1天进行了交易,那么如果第i天再进行交易就会将两次交易合并为一次交易。那么针对求local(i,j)这个问题,这里应该如何处理呢?由于第i天和第i-1天算是一次交易,所以,若要达到j次交易,只能是第i-1天就已经进行了j次交易,这是local(i-1,j) + diff的由来
二、如果第i-1天没有进行交易,那么第i天的交易就不会和前面的交易合并,所以前面一定是进行了j-1次交易才会满足条件。这里使用了global(i-1,j-1)表示前i-1天进行了j-1次交易的最大收益,当然这里有可能
global(i-1,j-1)==local(i-1,j-1),从而导致global(i-1,j-1) + diff = local(i-1,j-1) + diff = local(i,j-1),所以第一步可以弥补这里的缺点。
当然这里可能还有一个问题:如果上面的情况真的发生,那么
local(i,j) = max(local(i,j-1),local(i,j))这两个哪个会更大呢?会不会是第一个更大呢?