[LeetCode] Best Time to Buy and Sell Stock 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).

这道是买股票的最佳时间系列问题中最难最复杂的一道,前面两道Best Time to Buy and Sell Stock 买卖股票的最佳时间Best Time to Buy and Sell Stock II 买股票的最佳时间之二的思路都非常的简洁明了,算法也很简单。而这道是要求最多交易两次,找到最大利润,还是需要用动态规划Dynamic Programming来解,而这里我们需要两个递推公式来分别更新两个变量local和global,参见网友Code Ganker的博客,我们其实可以求至少k次交易的最大利润,找到通解后可以设定 k = 2,即为本题的解答。我们定义local[i][j]为在到达第i天时最多可进行j次交易并且最后一次交易在最后一天卖出的最大利润,此为局部最优。然后我们定义global[i][j]为在到达第i天时最多可进行j次交易的最大利润,此为全局最优。它们的递推式为:

local[i][j] = max(global[i - 1][j - 1] + max(diff, 0), local[i - 1][j] + diff)

global[i][j] = max(local[i][j], global[i - 1][j])

其中局部最优值是比较前一天并少交易一次的全局最优加上大于0的差值,和前一天的局部最优加上差值中取较大值,而全局最优比较局部最优和前一天的全局最优。代码如下:

解法一:

class Solution {
public:
    int maxProfit(vector<int> &prices) {
        if (prices.empty()) return 0;
        int n = prices.size(), g[n][3] = {0}, l[n][3] = {0};
        for (int i = 1; i < prices.size(); ++i) {
            int diff = prices[i] - prices[i - 1];
            for (int j = 1; j <= 2; ++j) {
                l[i][j] = max(g[i - 1][j - 1] + max(diff, 0), l[i - 1][j] + diff);
                g[i][j] = max(l[i][j], g[i - 1][j]);
            }
        }
        return g[n - 1][2];
    }
};

下面这种解法用一维数组来代替二维数组,可以极大的节省了空间,由于覆盖的顺序关系,我们需要j从2到1,这样可以取到正确的g[j-1]值,而非已经被覆盖过的值,参见代码如下:

解法二:

class Solution {
public:
    int maxProfit(vector<int> &prices) {
        if (prices.empty()) return 0;
        int g[3] = {0};
        int l[3] = {0};
        for (int i = 0; i < prices.size() - 1; ++i) {
            int diff = prices[i + 1] - prices[i];
            for (int j = 2; j >= 1; --j) {
                l[j] = max(g[j - 1] + max(diff, 0), l[j] + diff);
                g[j] = max(l[j], g[j]);
            }
        }
        return g[2];
    }
};

 本文转自博客园Grandyang的博客,原文链接:买股票的最佳时间之三[LeetCode] Best Time to Buy and Sell Stock III ,如需转载请自行联系原博主。

相关文章
|
Java Windows
JavaWebSocket心跳机制详解
WebSocket是一种在Web浏览器和服务器之间进行全双工通信的协议,它提供了一种简单而强大的方式来实现实时数据传输。在使用WebSocket时,心跳机制是非常关键的,它能够保持连接的稳定性并及时发现连接的异常。本文将详细解释JavaWebSocket心跳机制的实现原理和步骤。
759 0
|
11月前
|
移动开发 安全 API
微信H5支付--微信JS-SDK支付--点金计划
本文详细介绍了微信H5支付和JS-SDK支付的原理、配置和开发流程,涵盖了H5支付在移动端浏览器外唤起微信支付的细节,以及JS-SDK支付在微信内置浏览器中完成支付的相关注意事项。文章还针对微信支付常见问题,提供了解决方案和代码示例。最后,文章深入解析了微信支付点金计划,包括商家小票的自定义开发、API接口以及支付成功后的页面展示逻辑,为开发者提供了完整的开发参考。
681 0
微信H5支付--微信JS-SDK支付--点金计划
|
存储 数据库 开发者
作为一个Python爱好者,如何写出高可读性的代码?
作为一个Python爱好者,如何写出高可读性的代码?
作为一个Python爱好者,如何写出高可读性的代码?
|
SQL 存储 分布式计算
Hadoop中的Hive是什么?请解释其作用和用途。
Hadoop中的Hive是什么?请解释其作用和用途。
219 0
|
存储 Java 索引
【JAVA】 String 方法附件
【JAVA】 String 方法附件
128 0
|
人工智能 文字识别 自然语言处理
看了那场直播后,我们发起了一个讨论
看了那场直播后,我们发起了一个讨论
|
消息中间件 Java 测试技术
53分布式电商项目 - Spring集成ActiveMQ
53分布式电商项目 - Spring集成ActiveMQ
74 0
非递归方式实现二叉树的前、中、后序遍历
非递归方式实现二叉树的前、中、后序遍历
|
机器学习/深度学习 编译器 C语言
【程序的编译和预处理】源文件到可执行程序到底经历了什么?
【程序的编译和预处理】源文件到可执行程序到底经历了什么?
235 0
【程序的编译和预处理】源文件到可执行程序到底经历了什么?
|
存储 固态存储 安全
固态存储厂商忆联加入龙蜥社区,共建开源新生态
忆联将携手行业伙伴,持续拓展产品兼容生态圈,增进产业交流与合作,推动存储生态的发展与升级。
固态存储厂商忆联加入龙蜥社区,共建开源新生态