• 123. Best Time to Buy and Sell Stock III


    Problem statement:

    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).

    Solution one: DP(TLE)

    This problem is more complicated than 121. BestT time to Buy and Sell Stock. It allows at most two transactions, but you can not engage in multiple transactions at the same time. We have to finish one transaction and do another. These two transactions happen in order. 

    The explanation of DP idea can check 188. Best Time to Buy and Sell Stock IV.

    Time complexity is O(n * n). This solution can not pass OJ.

    class Solution {
    public:
        int maxProfit(vector<int>& prices) {
            if(prices.empty()){
                return 0;
            }
            int day_cnt = prices.size();
            vector<vector<int>> dp(3, vector<int>(day_cnt, 0));
            for(int i = 1; i <=2; i++){
                for(int j = 1; j < day_cnt; j++){
                    for(int m = 0; m < j; m++){
                        // find the max value if make a transaction at day j.
                        dp[i][j] = max(dp[i][j], prices[j] - prices[m] + dp[i - 1][m]);
                    }
                    // update dp[i][j] = max value between make a transaction at day j and do not make a transaction
                    dp[i][j] = max(dp[i][j], dp[i][j - 1]);
                }
            }
            return dp[2][day_cnt - 1];
        }
    };

    Solution two: two direction traverse(AC)

    According to what described in the question, we do two traverses: one from left to right to find the first max transaction, and another from right to left to find the second max transaction. It is worth to note that the value for each element means the max profit we can get by far, not the max profit for this transaction. 

    The similar questions which also need two directions traverse are 238. Product of Array Except Self and 581. Shortest Unsorted Continuous Subarray.

    Because it requires at max two transactions, we can do two directions traverse. This is a key point for this algorithm.

    The time complexity is O(n). It can pass OJ.

    class Solution {
    public:
        int maxProfit(vector<int>& prices) {
            if(prices.empty()){
                return 0;
            }
            int size = prices.size();
            vector<int> l2r(size, 0);
            vector<int> r2l(size, 0);
            
            int min_val = prices[0];
            int max_l2r = 0;
            for(int i = 1; i < size; i++){
                min_val = min(min_val, prices[i]);
                // get the maximum profit so far for first transaction
                l2r[i] = max(prices[i] - min_val, l2r[i -1]);
            }
            int max_val = prices[size - 1];
            for(int i = size - 2; i >= 0; i--){
                max_val = max(max_val, prices[i]);
                // get the maximum profit so far for second transaction
                r2l[i] = max(max_val - prices[i], r2l[i + 1]);
            }
            int max_profit = 0;
            for(int i = 0; i < size; i++){
                max_profit = max(max_profit, l2r[i] + r2l[i]);
            }
            return max_profit;
        }
    };

    This is a concise version:

    class Solution {
    public:
        int maxProfit(vector<int>& prices) {
            if(prices.empty()){
                return 0;
            }
            int size = prices.size();
            vector<int> l2r(size, 0);
            int min_val = prices[0];
            int max_l2r = 0;
            for(int i = 1; i < size; i++){
                min_val = min(min_val, prices[i]);
                l2r[i] = max(prices[i] - min_val, l2r[i -1]);
            }
            int max_val = prices[size - 1];
            int max_profit = 0;
            for(int i = size - 2; i >= 0; i--){
                max_val = max(max_val, prices[i]);
                max_profit = max(max_profit, max_val - prices[i] + l2r[i]);
            }
            return max_profit;
        }
    };

    Summary:

    This problem can be solved by two solutions. Basically, they belong to different computer methodologies.

    Solution one is DP, it is a general idea. As a computer programmer, we should and must could solve the problem by this approach. Although it can not pass OJ, it is still worthy to practice.

    Solution two, it reduced the time complexity and passed OJ. The main reason is at most 2 transactions, we can find one transaction from left to right and find another one from right to left, and update the max profit. It is also a common computer idea, some time is helpful to reduce the time complexity. 

  • 相关阅读:
    DNS 访问 Service【转】
    Service IP 原理【转】
    通过 Service 访问 Pod【转】
    定时执行 Job【转】
    并行执行 Job【转】
    Job 失败了怎么办?【转】
    用 k8s 运行一次性任务【转】
    运行自己的 DaemonSet【转】
    python之路——递归函数
    尝试加载 Oracle 客户端库时引发 BadImageFormatException
  • 原文地址:https://www.cnblogs.com/wdw828/p/6855019.html
Copyright © 2020-2023  润新知