下面是LeetCode的官方答案,我是在此基础上来理解答案。
写出这个程序其实一点都不困难,但是要理解还是真的很费劲。
DAYS | 0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|
prices | 1 | 3 | 4 | 8 | 4 | 9 |
cash | 0 | 0 | 1 | 5 | 5 | 8 |
hold | -1 | -1 | -1 | -1 | 1 | 1 |
手续费fee=2设置为在卖出股票时才支付。
【DAY 0】1
cash[0]:初始化为0,因为不持有任何股票
hold[0]:初始化为 -prices[1],也就是假设在第0天买入当天股票(其实有点像做空hha),是假设的话就是虚拟的,为了满足定义。
【DAY 1】3
cash[1]:
不持有股票,就是要把手上的股票卖出,那什么时候该卖出呢?
这里有两个问题:
一是手上的股票是什么?这个答案就在 hold[0] 中,hold[0]告诉我们手上的股票为1。
二是什么时候该卖出?当然是能够盈利的时候卖出, -1 + 3 - fee = 0 = cash[0] , 无所谓买卖,手上什么也没有
hold[1]:
持有股票,根据cash[1]的分析,现在要考虑买不买股票3,买股票3就会从当前不持有股票的最大收益中亏掉3,使得持有股票的收益为-3,这显然不如买股票1。
【DAY 2】4
cash[2]:
不持有股票,把手中的股票1卖掉,-1 + 4 - fee = 1,能盈利!还不赶紧卖?
hold[2]:
持有股票,这里也是为什么要把原题中的2改为4的原因。
根据cash[2],我们手上现在什么也没有了,只有赚的一点小钱1,如果这时再买入股票4,显然1 - 4 < -1,其实这是必然,当天卖出去了,再买入,不是白送手续费的钱给券商嘛?那么为什么要保持cash还是为-1呢?
个人认为这是在等待下一次买入的机会,但同时联想定义——持有股票时的最大收益,在未来不确定的情况下,持有股票1就是最佳选择。
【DAY 3】8
cash[3]:
不持有股票,把手中虚拟存在的股票1卖掉,-1 + 8 - fee = 5 > 1,能赚更多的钱,当然选择在这里卖掉!
hold[3]:
持有股票,与DAY 2的想法是一样的,目前看来持有股票1都是最佳选择:在DAY 2时由于选择了卖出股票,再持有股票的话,只能买入当天的股票4,就得从盈利1中扣掉4,显然-3不满足定义;同理再DAY 8时由于选择了卖出股票,再买入股票8就得从盈利5中扣掉8,显然-3不满足定义。所以继续保持我们上帝视角!保留股票1!
【DAY 4】4
cash[4]:
不持有股票,把手中虚拟存在的股票1卖掉,-1 + 4 - fee = 1 < 5,显然不如在DAY 3时卖掉,所以保持原有的状态。
hold[4]:
持有股票,现在不同了,我们已经赚了5,此时买入股票4,剩余1,显然比之前还保留虚拟股票1获得的收益大,这也就是在DAY 4时刻,持有股票的最大收益,在此之前,我们已经经历了一轮买卖。
这里需要多思考一点,如果今天的股价是7呢,最大持有收益就会变为-2,说明7并不是一个好的买点,那好的买点是什么呢?是5 - x > -1,x < 6,而恰好与最后的卖点8相差2,这个反过来想会好点,若x >= 6,那么在下一次在y卖出时,y起码要大于x+2,而这样就没有必要在中间断开了(如x = 6, y = 9,明显从1持有到9收益更大)!
【DAY 5】
cash[5]:
不持有股票,现在hold[4]为1了,手上的股票是什么呢?当然是股票4,然而这个信息从hold[4]中怎么看出来,其实不然,回归hold的定义,持有股票的最大收益,这里持有股票持有的是什么?是给我们带来最大持有收益时持有的股票!理解就是,在无论何时,我们手上都要有股票!不管是虚拟的还是真实的!拥有一支股票时才有的收益最大值 为-1时,因为定义必须得持有,所以为-1,为1时,是因为持有股票4是在进行一轮买卖后才买入的,而这次买入,是在增加持有收益的前提下。
此时,还要再理解一下cash,这个cash是不持有股票的最大收益,他是对前一天的hold买入再对比计算出来的,所以他是拥有某只股票时的最大收益+卖出该只股票+手续费的综合对比结果,可以这么理解在股票9卖出股票4,而股票4本上就携带了1元的收益。如果不是9而是7,7 - 1 - fee = 4 < 5明显不如不卖。
hold[5]:
持有股票,这个与之前DAY 3的思考是一样的,在DAY 5我们卖掉了股票,但是这是不是最佳卖点不知道,所以开启上帝模式,保持一个虚拟的状态。