力扣第309题“最佳买卖股票时机含冷冻期”的解题思路

参考代码:

class Solution {
    public int maxProfit(int[] prices) {
        int n=prices.length;
        if(n==0)return 0;
        int[] hold=new int[n];
        hold[0]=-prices[0];
        int[] notHold=new int[n];
        for(int i=1;i<n;i++){
            if(i>=2)hold[i]=Math.max(hold[i-1],notHold[i-2]-prices[i]);
            else hold[i]=Math.max(hold[i-1],-prices[i]);
            notHold[i]=Math.max(notHold[i-1],hold[i-1]+prices[i]);
        }
        return notHold[n-1];
    }
}

大致思路:

此题展现出来的维度有三个。思路是先降维,将买、卖、冷冻,降维成两个维度:持有股票和未持有股票。 持有股票:今天买入和之前买入但未卖出 未持有:今天卖出和冷冻期 所以有传递式: hold[i]=max(hold[i-1],notHold[i-2]-prices[i]); 意思是当前持有的股票的最大收益是昨天持有的股票(可能今天并未有任何操作)和之前卖出的最大收益-今天买入的(i-2的意思是今天买入的话,昨天就应该是冷冻期也有可能没有操作,所以notHold[i-1]=notHold[i-2]。)。 notHold[i]=max(notHold[i-1],hold[i-1]+prices[i]);最大收益的就很容易理解。(摘自力扣作者没事就来刷刷)

弄清这道题就需要弄清两个问题:

一:为什么是hold[i]=notHold[i-2]-prices[i],而不是hold[i]=notHold[i-1]-prices[i],因为在第i-1天可能进行了卖出操作,那么中间就存在一天的冷冻期,此时就不成立了。

二:为什么hold[i]=notHold[i-2]-prices[i]则是必然正确的。因为nothold是不减的序列,如果i-1天是卖出pass掉的话那i-2天就是最大的,如果i-1天是未操作或冻结那么i-1就等于i-2。

具体实现:

首先排除特殊情况,长度为0时,return 0;

创建hold和notHold两个数组,并且hold[0]=-prices[0],因为持有股票就需要买进股票,所以是负的。

if(i>=2)hold[i]=Math.max(hold[i-1],notHold[i-2]-prices[i]);因为notHold从第0个开始,所以i-2需有意义,则i>=2,也可以理解为当i=1时,可以是买进prices[0]那天的股票,也就是hold[0],也可以不买prices[0]那天的股票,买prices[1]那天的股票,买进所以是负。

notHold[i]=Math.max(notHold[i-1],hold[i-1]+prices[i]);不持有的最大收益可以是昨天也不持有股票的最大收益和昨天持有股票今天卖出的最大收益。

因为notHold是不减的(求的总是最大值),所以直接返回最后一个即notHold[n-1]。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值