做了下这个题, 感觉自己还是很菜,竟然还要看答案

 

这个题目告诉你股票价格,计算怎么交易收入最大;毫无疑问, 最低点买入,最高点卖出

先上答案;

 1     int maxProfit(vector<int>& prices, int fee) {
 2         int income=0;
 3         int cost=-prices[0];
 4         for(int i=1;i<prices.size();++i)
 5         {
 6             income=max(prices[i]+cost-fee,income);//收入=max(今天卖出,今天不卖出)
 7             cost=max(cost,income-prices[i]); 余额=max(今天不做操作,今天买入)
 8         }
 9         return income;
10     }

 

第一次看这个答案,都完全不理解,菜鸡就是菜鸡。。 现在记录一下这个答案的详细解说,如果你跟我一样是个菜鸡, 应该也能看懂;

以下图解假设手续费为0,减小干扰

先解释下用到的两个变量: cost 每一天我的余额,income 每一天如果卖出股票能挣多少钱

第一天, 初始化, 收入=0; 余额=今天买入=-1  , 注意这里一定记为买入的情况,不然后面没法比较

 

第二天,股票涨到3块,收入=max(今天卖出=3-1=2,今天不操作=0)= 2, 余额=max(不操作=-1,买入今天股票=2-3=-1),两者相等都是-1;

开始我对这里产生了疑问,收入和余额都会做赋值,会不会乱套?

收入=max(卖出,不卖出)

余额=max(买入,不买入)

那么岂不是四种组合?

然后一想,理论上是,但实际上并不会发生4种,只会有两种  卖出+不买入   和   不卖+买入 , 而这两种也是符合题目条件和实际情况的,

另外两种组合   卖出+买入,  不卖出+不买入  不会发生

分析下为什么只会发生两种;

如果今天的价格较高,那么 执行 收入=max(卖出,不卖出) 时,会命中左边条件,也就是 收入=卖出 ,并且 余额=max(买入,不买入)  也会命中右边条件,也就是余额=不买入;非常神奇。。

同理,如果今天价格很低, 两个等式会命中相反的价格;

所以这种写法表面上给人有4种组合的感觉,其实不是;估计是大神进行优化的代码写法,两行就搞定了;

下面是我自己还原的代码,逻辑上好理解;

    int maxProfit(vector<int>& prices, int fee) {
        int income=0; 初始收益为0
        int cost=-prices[0]; 初始余额为第一天股价 x -1
        for(int i=1;i<prices.size();++i)
        {
            int sell=prices[i]+cost-fee; // 先检查今天卖出收益是多少;这步要先做
            if(sell>income) 如果比昨天卖出要高,用今天的结果刷新昨天的值
            {
                income=sell;
                continue; 无需检查余额
            }
            cost=max(cost,income-prices[i]); 如果今天不适合卖出(不卖出有两种情况,股价走低或者股价变高但不足以支付手续费),再看要不要买入;买入标准,用收入减股价是否比余额要多
        }
        return income;
    }

 

再往后的图就不画了,其实后面的天数循环逻辑和第二天都是一样的了,只要第二天的逻辑清楚就行了;

 


 

深度思考,这个题本质是什么?

在我琢磨了好久之后, 这个题其实压根和股票没有卵关系...

这个题在不考虑手续费的情况下, 不就是让你找出所有的连续递增子数组么!!!!