问题

假设你有一个数组,其中的第i个元素表示一只股票在第i天的价格。

设计一个算法找出最大的利润值。你最多只能进行两次交易。

注意:

你不能在同一时间进行多次交易(即你必须在再次买入股票之前卖出当前的股票)

初始思路

我们先来考虑只能进行一次交易的情况,即只能买入并卖出一次。可以尝试在第一天就买入股票,然后按顺序计算后面每一天卖出股票后的利润。将该利润和一个保存最大利润的变量比较,如果更大就更新最大利润。很显然,第一天就买入并在利润最大时卖出肯定不会是所有情况的答案,因为股票的价格是会下跌的。那么在什么情况下我们考虑尝试改变买入的时间呢?和第一天买入的价格相比,后面的价格无非就分两种情况:

  • 价格更高。这种情况显然是不可能出现优于第一天买入的利润的。因为[从这天之后第一天买入可能的最高利润]=[第一天到该天的利润]+[该天买入可能的最高利润]。所以这种情况下我们需要维持第一天买入的选择。
  • 价格一样或更低。[从这天之后第一天买入可能的最高利润]=[该天买入可能的最高利润]- [第一天到该天的亏损]。这种情况下在该天买入就有可能创造最高利润了。

如此一来我们就可以得到一个O(n)的算法:

设置买入价为第一天的价格

从第二天价格遍历存放价格的数组

如果该天卖出利润 > 0

        如果利润大于当前最大利润,更新最大利润

    如果该天卖出利润 <= 0

        设置买入价为该天价格

现在让我们考虑两次交易的情况。因为不能在没卖出股票的情况下再次买入,所以两次买入卖出的区间是不能交叉的。那么我们可以在用上述方法找到一个新的最大利润后,从下一天开始用同样方法再找一次最大利润。将两个利润相加后尝试更新一个总的最大利润。注意处理完后外层的遍历不能中断,还要继续查找直到遍历完毕。伪代码变化如下:

计算利润

设置买入价为第一天的价格

从第二天价格遍历存放价格的数组

如果该天卖出利润 > 0

        如果利润大于当前最大利润,更新最大利润

           如果是在外层函数

               第二次利润 = 计算利润(当前天数+1作为第一天)

              如果利润+第二次利润大于总最大利润,更新总最大利润

    如果该天卖出利润 <= 0

        设置买入价为该天价格

如果是在外层函数,返回总最大利润

否则返回当前最大利润

转换成C++代码后如下:

 1 class Solution {
 2     public:
 3         int maxProfit(std::vector<int> &prices)
 4         {
 5             return CaculateProfit(prices, 0, FIRST).profit;
 6         }
 7
 8     private:
 9         struct Profit
10         {
11             Profit() : profit(0), buyPrice(-1), buyDay(0), sellDay(0)
12             {
13             }
14
15             int profit;
16             int buyPrice;
17             int buyDay;
18             int sellDay;
19         };
20
21         enum Transaction
22         {
23             FIRST,
24             SECOND
25         };
26
27         Profit CaculateProfit(std::vector<int> &prices, int start, Transaction transaction )
28         {
29             Profit currentProfit;
30             Profit maxProfit;
31             Profit secondProfit;
32             Profit totalProfit;
33
34             for(int day = start; day < prices.size(); ++day)
35             {
36                 if(currentProfit.buyPrice == -1)
37                 {
38                     currentProfit.buyPrice = prices[day];
39                     currentProfit.buyDay = day;
40                     continue;
41                 }
42
43                 currentProfit.profit = prices[day] - currentProfit.buyPrice;
44                 currentProfit.sellDay = day;
45
46                 if(currentProfit.profit < 0)
47                 {
48                     currentProfit.buyPrice = prices[day];
49                     currentProfit.buyDay = day;
50                     currentProfit.profit = 0;
51                 }
52
53                 if(currentProfit.profit > maxProfit.profit)
54                 {
55                     if(transaction == FIRST)
56                     {
57                         secondProfit = CaculateProfit(prices, day + 1, SECOND);
58
59
60                         if(currentProfit.profit + secondProfit.profit > totalProfit.profit)
61                         {
62                             totalProfit.profit = currentProfit.profit + secondProfit.profit;
63                         }
64                     }
65
66                     maxProfit = currentProfit;
67                 }
68             }
69
70             if(transaction == FIRST)
71             {
72                 return totalProfit;
73             }
74             else
75             {
76                 return maxProfit;
77             }
78         }
79     };

maxProfit

提交后顺利通过Judge Large。

转载于:https://www.cnblogs.com/shawnhue/archive/2013/06/09/leetcode_123.html

[LeetCode 123] - 买入与卖出股票的最佳时机III(Best Time to Buy and Sell Stock III)相关推荐

  1. 【DP + 卖股票】LeetCode 123. Best Time to Buy and Sell Stock III

    LeetCode 123. Best Time to Buy and Sell Stock III Solution1: 不得不让人感叹算法之精妙啊!!! 参考网址:[1]http://www.cnb ...

  2. Leetcode Best Time to Buy and Sell Stock III

    Leetcode Best Time to Buy and Sell Stock III,本算法的关键为找出其动态子结构.可以发现,序列中的最小值可以做为其的一个分割,令左边序列为left,右边的序列 ...

  3. Best Time to Buy and Sell Stock III

    解题思路来自:https://blog.csdn.net/u012501459/article/details/46514309 Say you have an array for which the ...

  4. Leetcode_123_Best Time to Buy and Sell Stock III

    本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/43740415 Say you have an array ...

  5. leetcode 123. Best Time to Buy and Sell Stock III | 123. 买卖股票的最佳时机 III(总结DP 模型套路)

    题目 https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/description/ DP 模型套路 DP 套路之:暴力递 ...

  6. LeetCode 123. 买卖股票的最佳时机 III(Best Time to Buy and Sell Stock III)

    题目描述: 给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你最多可以完成 两笔 交易. 注意: 你不能同时参与多笔交易(你必须在再次购买 ...

  7. C#LeetCode刷题之#121-买卖股票的最佳时机(Best Time to Buy and Sell Stock)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/4014 访问. 给定一个数组,它的第 i 个元素是一支给定股票第  ...

  8. 123 Best time to buy and sell stock iii

    题解: 根据题目要求,最多进行两次买卖股票,而且手中不能有2只股票,就是不能连续两次买入操作. 所以,两次交易必须是分布在2各区间内,也就是动作为:买入卖出,买入卖出. 进而,我们可以划分为2个区间[ ...

  9. [leetcode]Best Time to Buy and Sell Stock III

    先说思路.参考了这篇:http://blog.unieagle.net/2012/12/05/leetcode%E9%A2%98%E7%9B%AE%EF%BC%9Abest-time-to-buy-a ...

最新文章

  1. linux日志管理命令详解
  2. Matlab如何读取文本文件
  3. C#-Stmp发邮件
  4. mysql char null_关于mysql设置varchar 字段的默认值''和null的区别,以及varchar和char的区别...
  5. C++课程设计,12306模拟写起来就是这么粗暴
  6. WebAssembly生态将完善网络安全性
  7. 理解纯CSS画三角形
  8. Core官方DI解析(3)-ServiceCallSite.md
  9. 51 nod 1521 一维战舰 时间复杂度O(n),同 Codeforces 567D. One-Dimensional Battle Ships 有详细注释...
  10. 如何更高效地学习3D视觉?
  11. HttpServletRequest中文乱码
  12. 如何实现台达触摸屏与台达PLC之间的远距离无线数据交换?
  13. 黑色脸谱_上演三幕的脸谱剧
  14. 那些小众却深得网友喜爱的导航网站
  15. 【小学】综合素质脑图笔记
  16. 逆向工具之脱壳神器反射大师(附脱壳环境搭建、脱壳实战)
  17. Linux FFmpeg依赖库编译
  18. 换goland主题皮肤
  19. 有一个勤奋好学积极向上的男朋友是一种什么样的体验…
  20. 【51单片机实验笔记】2. 数码管的基本控制

热门文章

  1. Could not find a suitable table factory for ‘org.apache.flink.table.factories.CatalogFactory‘
  2. hbase映射为hive表(转载+整理+自己验证)
  3. Your STATICFILES_DIRS setting is not a tuple or list
  4. 大话数据结构 : 二叉排序树
  5. keras版本 str object has no attribute decode
  6. Python学习——import语句导入模块顺序
  7. 【数学基础】参数估计之贝叶斯估计
  8. cbitmap 从内存中加载jpg_[转载]windows照片查看器无法显示图片内存不足
  9. python实现快速创建订单_从销售订单和Od中的产品订单创建新记录
  10. nodejs mysql 增删改查_Nodejs操作MySQL-增删改查