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

当遇到限制次数以及求最大的要求时,很自然要联想到动规。

动规中不同的状态设计,会有不同的时间复杂度。

本题有两种解法:

(1)

我最开始想到的是下面这种解法,但是Memory Limit Exceeced.

O(n^2)的解法

很自然的我们会想到记录从开头到第i个字符中进行k次交易能够得到的最大收益,记为dp[i][k].

进行更新:dp[i][k] = max{dp[j][k-1]+maxprofit(j...i)}, 0 <= j < i

这里我们需要用到每个可能的区间中进行一次交易的最大收益,也就是I中的问题。

预先计算出所有的maxprofit的复杂度是O(n^2),dp的复杂度也是O(n^2).

Code:

class Solution {
public:
int maxProfit(vector<int> &prices) {
int n = prices.size();
if(n == 0) return 0;
vector<vector<int>> dp(n, vector<int>(3,0));
vector<vector<int>> maxprofit(n, vector<int>(n, 0)); for(int i = 0; i < n; i++)
{
int curmin = prices[i];
int curprofit = 0;
for(int j = i+1; j < n; j++)
{
if(prices[j] < curmin) curmin = prices[j];
else{
int gap = prices[j] - curmin;
if(gap > curprofit) curprofit = gap;
}
maxprofit[i][j] = curprofit;
if(i == 0) dp[j][1] = curprofit;
}
} for(int i = 1; i < n; i++)
{
int tmp = dp[0][1] + maxprofit[0][i];
for(int j = 1; j < i; j++)
{
if(dp[j][1] + maxprofit[j][i] > tmp) tmp = dp[j][1]+maxprofit[j][i];
}
dp[i][2] = tmp;
} return dp[n-1][2];
}
};

(2)O(n)的解法

参考了这个:http://blog.csdn.net/linhuanmars/article/details/23236995

从上面的分析中我们很容易找出一个case, 例如有一个区间差异特别大,在很长时间内都是最优的选择,而我们的dp却需要不断的枚举一些不可能构成最终解的区间。

怎么样更聪明的定义状态呢?

上一种定义中,我们是定义(i,j)中的最大的解,这样不同的(i,j)对对应的可能是同一种解;这样我们可以用一个global变量来存储;但是由于处理的区间是不断延伸的,后面出现的数字可能和当前末尾的组合起来行程更大的区间,因此我们用一个local变量存储当前以i结尾的最大的解的值。

扩展到能够选择k个区间,我们定义:

global(i,k) 表示截止到第i天,进行k次交易能够获得的最优解(不一定以最后一天结束)

local(i,k) 表示以第i天结束的k次交易能够获得的最优解

能够得到递推式:

local[i][k] = max{global[i-1][k-1], local[i-1][k]} + prices[i] - prices[i-1];

global[i][k] = max{global[i-1][k], local[i][k]};

初始值全为零,最终解为global[n-1][2]。

Code:

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

 

从其他博客中找到了一种O(n)的解法,思路更简单,但是不具备从2次交易推广到k次的潜力。

主要的思路就是从前往后扫描一遍,找到从0到i的一次交易的最大收益,然后从后往前扫描一遍,得到从i+1到n-1的最大收益。然后两者相加取最大即可。

传送门:http://fisherlei.blogspot.com/2013/01/leetcode-best-time-to-buy-and-sell_3958.html

4 Best Time to Buy and Sell Stock III_Leetcode的更多相关文章

  1. [LeetCode] Best Time to Buy and Sell Stock with Cooldown 买股票的最佳时间含冷冻期

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

  2. [LeetCode] Best Time to Buy and Sell Stock IV 买卖股票的最佳时间之四

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

  3. [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 al ...

  4. [LeetCode] Best Time to Buy and Sell Stock II 买股票的最佳时间之二

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

  5. [LeetCode] Best Time to Buy and Sell Stock 买卖股票的最佳时间

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

  6. [LintCode] Best Time to Buy and Sell Stock II 买股票的最佳时间之二

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

  7. [LintCode] Best Time to Buy and Sell Stock 买卖股票的最佳时间

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

  8. LeetCode——Best Time to Buy and Sell Stock II (股票买卖时机问题2)

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

  9. 123. Best Time to Buy and Sell Stock (三) leetcode解题笔记

    123. Best Time to Buy and Sell Stock III Say you have an array for which the ith element is the pric ...

随机推荐

  1. 各种主流浏览器CSS、BUG兼容

    1.div的垂直居中问题 vertical-align:middle;将行距增加到和整个DIV一样高 line-height:200px;然后插入文字,就垂直居中了.缺点是要控制内容不要换行.---- ...

  2. ruby 基础知识(二)

    ruby  中的动态方法 http://singleant.iteye.com/blog/1680382 Rails 大量使用了符号(symbol).符号看上去很像变量名,不过以冒号作为前缀.符号的例 ...

  3. python画决策树

    1.安装graphviz.下载地址在:http://www.graphviz.org/.如果你是linux,可以用apt-get或者yum的方法安装.如果是windows,就在官网下载msi文件安装. ...

  4. libvirt 网络手册(一)

    如果选择网络类型 在一个专用的服务器上,虚拟机常常需要被从公网访问(也就是每个虚拟机都需要公网地址),这时就需要桥接网络,它使得每个虚拟机有自己的IPV4和IPV6地址.如果桥接不可用,可以创建一个R ...

  5. eclipse软件创建servlet

    网上找了好多资料,eclipse创建servlet后,发到tomcat下发布,不能编译,生产class文件. 很多回答的都是一知半解,太气人了,看书.把资料找了一天,才发现是没有servlet-api ...

  6. ubuntu15:10 163源

    sudo vim /etc/apt/sources.list deb http://mirrors.163.com/ubuntu/ wily main restricted universe mult ...

  7. CapsLock与ctrl的键位修改

    windows下修改方式: linux下修改方式: 在用户目录下新建文档命名为keychange.sh 编辑以下内容: remove Lock = Caps_Lock remove Control = ...

  8. sql server2008给数据表,字段,添加修改注释

    1 -- 表加注释 2 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'注释内容' , @level0type=N' ...

  9. MySql: 常见sql语句

    1. show create table mysql> show create table t \G*************************** 1. row ************ ...

  10. php实验5数组

    1.自定义两个数组,分别为索引数组和关联数组,每个数组必须至少有4个元素,使用print_r( )函数输出数组元素. 2.编写一个随机抽奖程序,示例运行结果如下: 3.定义一个三维数组$categor ...