• 123. Best Time to Buy and Sell Stock III (Array; DP)


    Say you have an array for which the ith element is the price of a given stock on day i.

    Design an algorithm to find the maximum profit. You may complete at most two transactions.

    Note:
    You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).

    法I:把要求的东西profits设成状态。

    第一次:从左往右扫描,同I一样记录下minimum value,不同的是,不仅要知道最大profit,还要记录下每个当前位置的profit(需要一个数组),为了之后与第二次扫描的结果相加。

    第二次:从右往左scan,记录下maximum value, 计算profit,再加上之前第一次扫描从0到当前位置的profit,得到总的profit。

    时间复杂度O(n) *2

    class Solution {
    public:
        int maxProfit(vector<int> &prices) {
            if(prices.empty()) return 0;
           
            int size = prices.size();
            int maxProfit = 0;  
            int* profits = new int [size]; //表示从0到i的最大利润
            int* profits_from_last = new int [size]; //表示从i到size-1的最大利润
            
            //initial status    
            profits[0] = 0;
            int minValue = prices[0];
      
           //scan from start          
            for(int i = 1; i< size; i++)
            {
                if(prices[i] < minValue) //save the minimum value
                {
                    minValue = prices[i];
                    profits[i] = profits[i-1];
                }
                else //caculate the profit from minimum value to currentand compare to previous maximum profit(profits[i-1])
                {
                    profits[i] = max(prices[i]-minValue,profits[i-1]);
                }
                 
            }
            
            //initial status
            profits_from_last[size-1] = 0;
            int maxValue = prices[size-1];
            
            //scan from last
            for(int i = size-2; i >=0 ; i--)
            {
                 if(prices[i] > maxValue) //save the maximum value
                 {
                     maxValue = prices[i];
                     profits_from_last[i] = profits_from_last[i+1];
                 }
                 else //caculate the profit from current to maximum value and compare to previous maximum profit(profits_from_last[i+1]) 
                 {
                     profits_from_last[i] = max(maxValue-prices[i],profits_from_last[i+1]);
                 }
                
                 int profit = profits[i] + profits_from_last[i]; //calculate profits of two transactions
                 if(profit>maxProfit)
                 {
                     maxProfit = profit;
                 }
            }
            return maxProfit;      
        }
    };

    Note:第二次scan不必存储每个状态,所以只需一个变量存储到目前为止第二次扫描的最大利润。

    class Solution {
    public:
        int maxProfit(vector<int> &prices) {
            if(prices.empty()) return 0;
           
            int size = prices.size();
            int maxProfit = 0;  
            int* profits = new int [size]; //表示从0到i的最大利润
            int* profits_from_last = new int [size]; //表示从i到size-1的最大利润
            
            //initial status    
            profits[0] = 0;
            int minValue = prices[0];
      
           //scan from start          
            for(int i = 1; i< size; i++)
            {
                if(prices[i] < minValue) //save the minimum value
                {
                    minValue = prices[i];
                    profits[i] = profits[i-1];
                }
                else //caculate the profit from minimum value to currentand compare to previous maximum profit(profits[i-1])
                {
                    profits[i] = max(prices[i]-minValue,profits[i-1]);
                }
                 
            }
            
            //initial status
            int maxSecondProfits = 0;
            int maxValue = prices[size-1];
            
            //scan from last
            for(int i = size-2; i >=0 ; i--)
            {
                 if(prices[i] > maxValue) //save the maximum value
                 {
                     maxValue = prices[i];
                 }
                 else //caculate the profit from current to maximum value and compare to previous maximum profit(maxSecondProfits) 
                 {
                     maxSecondProfits = max(maxValue-prices[i],maxSecondProfits);
                 }
                
                 int profit = profits[i] + maxSecondProfits; //calculate profits of two transactions
                 if(profit>maxProfit)
                 {
                     maxProfit = profit;
                 }
            }
            return maxProfit;      
        }
    };

     法II:进一步提升space efficiency。扫描一次,从而不用存储第一次交易的状态。

    在扫描的时候,把当前点看作两次交易都完成的点,计算当前最大利润。

    然后再依次更新把当前点看作第二次买入点的最大利润,看作第一次卖出点的最大利润,第一次买入点的最大利润,这些都为了在下一个循环用来更新状态。

    所以,需要用4个变量存储到当前日为止第1/2次买入/卖出的利润最大值。

    时间复杂度O(n)

    class Solution {
    public:
        int maxProfit(vector<int>& prices) {
            int dates = prices.size();
            if(dates <= 1) return 0;
            
            int hold1 = INT_MIN, hold2 = INT_MIN;//buy stock
            int release1 = 0, release2 = 0;//sell stock
            
            for(int i = 0; i < dates; i++){
                release2 = max(release2, hold2+prices[i]);// The maximum if we've just sold 2nd stock so far.
                hold2 = max(hold2, release1 - prices[i]); // The maximum if we've just buy  2nd stock so far.
                release1 = max(release1, hold1+prices[i]);// The maximum if we've just sold 1nd stock so far.
                hold1 = max(hold1, -prices[i]);           // The maximum if we've just buy  1st stock so far. 
            }
            return release2;
        }
    };
  • 相关阅读:
    MianShiTi
    C#多线程解决界面卡死问题的完美解决方案
    C#中的WebBrowser控件的使用
    解决Linq第一次调用存储过程时速度慢的问题
    AX 的 NumberSequences
    Ax 从一个form关闭另外一个form,AX全局变量
    查询数据库后台Block 的Sql存储过程
    Dynamic AX 4.0 用户组权限SecurityKey
    20160408 从软件工程的3大文档开始说起
    获取AX的窗口所有控件的lableID及内容
  • 原文地址:https://www.cnblogs.com/qionglouyuyu/p/4878356.html
Copyright © 2020-2023  润新知