• [LeetCode]107. Best Time to Buy and Sell Stock III股票买卖III


    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、股票买卖II又有些不同,这次要求最多交易两次,还是动态规划的方法。我们可以分别计算出在第i(1<=i<=n)天前交易一次股票所能获得的最大收益和第i(1<=i<=n)天后交易一次股票所能获得的最大收益,于是能计算出以第i(1<=i<=n)天为分割交易两次所能获得的最大收益,于是一共交易两次所能获得的最大收益必是所有收益的最大值。注意计算前后收益时都必须包含第i天,因为当天可以先卖出然后买进。

    class Solution {
    public:
        int maxProfit(vector<int> &prices) {
            int n = prices.size(), maxp = 0;
            if (n < 2) return 0;
            vector< vector<int> > maxOne(2, vector<int>(n, 0));
            maxOne[0][0] = 0;
            maxOne[1][n - 1] = 0;
            for (int i = 1; i < n; ++i)
                maxOne[0][i] = maxProfitOfOne(prices, 0, i);
            for (int i = n - 2; i >= 0; --i)
                maxOne[1][i] = maxProfitOfOne(prices, i, n - 1);
            for (int i = 0; i < n; ++i)
                maxp = max(maxp, maxOne[0][i] + maxOne[1][i]);
            return maxp;
        }
    private:
        int maxProfitOfOne(vector<int>& prices, int beg, int end) {
            int maxp = 0, curMin = prices[beg];
            for (int i = beg + 1; i <= end; ++i) {
                curMin = min(curMin, prices[i]);
                maxp = max(maxp, prices[i] - curMin);
            }
            return maxp;
        }
    };

    直接调用maxProfitOfOne会超时Time Limit Exceeded,因为计算第i天前后各交易一次的最大收益时要遍历[0,i]和[i,n-1]两半数组,这样相当于整个时间复杂度为O(n^2)了,必须加以改进。

    注意到第i天前的最大收益要么是第i-1天前的最大收益,要么是第i天的股票价格减去前i-1天的最低价格;而第i天后的最大收益要么是第i+1天后的最大收益,要么是后i+1天的最高股票价格减去第i天的价格,因此可以简化如下:

    class Solution {
    public:
        int maxProfit(int k, vector<int>& prices) {
            int n = prices.size(), maxp = 0;
            if (n < 2) return 0;
            int curMin = prices[0];
            vector< vector<int> > maxOne(2, vector<int>(n, 0));
            maxOne[0][0] = 0;
            maxOne[1][n - 1] = 0;
            for (int i = 1; i < n; ++i) {
            maxOne[0][i] = max(maxOne[0][i - 1], prices[i] - curMin);
                curMin = min(curMin, prices[i]);
            }
            int curMax = prices[n - 1];
            for (int i = n - 2; i >= 0; --i) {
                maxOne[1][i] = max(maxOne[1][i + 1], curMax - prices[i]);
                curMax = max(curMax, prices[i]);
    
            }
            for (int i = 0; i < n; ++i)
                maxp = max(maxp, maxOne[0][i] + maxOne[1][i]);
            return maxp;
        }
    };

     其他解法参见http://www.cnblogs.com/grandyang/p/4281975.html

  • 相关阅读:
    sql中压缩日志文件和ntextl转化为varchar的处理
    一个生成验证字符或数字的增强类(downmoon)(基于.net1.1)及调用示例
    web程序中获取应用程序系统变量的方法( For.net 1.1)
    ASP.NET 中的正则表达式MSDN(2)
    让sourceSafe每天自动备份及修复(适用于vss6.0和vss2005)
    用SQL语句修改字段的默认值
    关于.net2.0中Webconfig中连接串的加密
    软件工厂简介自MSDN
    获取SqlServer 2000中字段的备注信息
    使用.NET 向浏览器写入二进制文件
  • 原文地址:https://www.cnblogs.com/aprilcheny/p/5040118.html
Copyright © 2020-2023  润新知