逐步分析- 买卖股票的最佳时机含手续费

問題描述:
给定一个整数数组 prices,其中 prices[i]表示第 i 天的股票价格 ;整数 fee 代表了交易股票的手续费用。

你可以无限次地完成交易,但是你每笔交易都需要付手续费。如果你已经购买了一个股票,在卖出它之前你就不能再继续购买股票了。

返回获得利润的最大值。

注意:这里的一笔交易指买入持有并卖出股票的整个过程,每笔交易你只需要为支付一次手续费。
示例
输入:prices = [1, 3, 2, 8, 4, 9], fee = 2
输出:8
解释:能够达到的最大利润:
在此处买入 prices[0] = 1
在此处卖出 prices[3] = 8
在此处买入 prices[4] = 4
在此处卖出 prices[5] = 9
总利润: ((8 - 1) - 2) + ((9 - 4) - 2) = 8
思路:
首先股票問題可以大概分爲三種情況:
1.股價一直上升,這種情況顯然我們只需要第一天買入、最後賣出。(前提利潤比費用高)
2.股價一直下跌,這種情況,我們當然不買入。
3.股價有漲有跌

第三種情況其實才是我們需要重點考慮的對象。

有漲有跌的情況
顯然,如果只有一次交易機會,我們只需要找最低的買入點和最高的賣出點就行了。
例如:對於prices = [1, 3, 2, 8, 4, 9]
如果只有一次機會,顯然是價格1買入,價格9賣出。

但是,對於多次交易的情況。是存在多次“小交易”累積之和大於一次“大交易”的情況。
例如prices = [1, 3, 2, 8, 4, 9]。
該例中,設買入費為2,則有
8-1-2+9-4-2>9-1-2
再觀察上式:可以簡化為
8-4>2
我們直觀觀察,可以得出:
如果“大交易(如1-9)中上一次”小交易價格(8)比下次小交易價格(4)大出費用(2)以上,那麽一次大交易就不如兩次小交易。就應該重新買入。反之,就應該只進行一次大交易。

代碼實現:

在这里插入代码片
int maxProfit(vector<int>& prices, int fee) {
        if(prices.size()==1) return 0;
        int sum=0;
        int left=prices[0];
        int right=0;
        for(int i=1;i<prices.size();++i)
        {  
            if(right-prices[i]>fee)  //大交易不如多次小交易的情況
            {
                sum+=(right-left-fee);/*纍積利潤*/
                left=prices[i];/*買入點更新*/
                right=0;/*賣出點重置*/
            } 
            if(left>=prices[i]) left=prices[i];
            else if(prices[i]-left>fee) right=max(prices[i],right);/*以上是追求最小買入點和最大賣出點*/
        }
         if(right-left>=fee) sum+=(right-left-fee);//只有大交易的情況
        return sum;
    }


 

你可能感兴趣的:(个人笔记,贪心算法,算法,leetcode)