[LeetCode] Best Time to Buy and Sell Stock III
将Best Time to Buy and Sell Stock的如下思路用到此题目
思路1:第i天买入,能赚到的最大利润是多少呢?就是i + 1 ~ n天中最大的股价减去第i天的。
思路2:第i天买出,能赚到的最大利润是多少呢?就是第i天的价格减去 0~ i-1天中最小的。
和前两道题比起来的话,这道题最难了,因为限制了交易次数。
解决问题的途径我想出来的是:既然最多只能完成两笔交易,而且交易之间没有重叠,那么就divide and conquer。
设i从0到n-1,那么针对每一个i,看看在prices的子序列[0,...,i][i,...,n-1]上分别取得的最大利润(第一题)即可。
这样初步一算,时间复杂度是O(n2)。
改进:
改进的方法就是动态规划了,那就是第一步扫描,先计算出子序列[0,...,i]中的最大利润,用一个数组保存下来,那么时间是O(n)。
第二步是逆向扫描,计算子序列[i,...,n-1]上的最大利润,这一步同时就能结合上一步的结果计算最终的最大利润了,这一步也是O(n)。
所以最后算法的复杂度就是O(n)的。
/*
解释:
首先,因为能买2次(第一次的卖可以和第二次的买在同一时间),但第二次的买不能在第一次的卖左边。
所以维护2个表,f1和f2,size都和prices一样大。
意义:
f1[i]表示 -- 截止到i下标为止,左边所做交易能够达到最大profit;[0,...,i]的利润
f2[i]表示 -- 截止到i下标为止,右边所做交易能够达到最大profit;[i,...,n-1]的利润
那么,对于f1 + f2,寻求最大即可。
*/
对于f1[i],求解过程中用price[i] 减去之前的最小值 和 f1[i-1]做比较,取最大值
动态规划转移方程 f1[i] = max(f1[i-1], price[i]- min)
对于f2[i],求解过程中用后面的最大值减去price[i]和f2[i+1]做比较,取最大值
动态规划转移方程 f2[i] = max(f2[i+1], max-price[i])
思路解释完毕,上code:
minX[i] 表示0 到 i 的最小值 的price
max[i] 表示i到n-1的最大值的price
class Solution {
public:
int maxProfit(vector<int> &prices) {
if (prices.size() == )
return ;
vector<int> f1(prices.size());
vector<int> f2(prices.size());
vector<int> minX(prices.size());
vector<int> maxX(prices.size());
minX[] = prices[];
for(int i = ; i< prices.size();i++ )
{
minX[i] = min(minX[i-], prices[i]);
}
maxX[prices.size()-] = prices[prices.size()-];
for(int i = prices.size() -; i >=; i-- )
{
maxX[i] = max(maxX[i+], prices[i]);
}
f1[] = ;
for(int i = ; i< prices.size();i++ )
{
f1[i] = max(f1[i-],prices[i]-minX[i]);
}
f2[prices.size()-] = ;
for(int i = prices.size() -; i >=; i-- )
{
f2[i] = max(f2[i+],maxX[i]- prices[i]);
}
int sum = ;
for(int i = ; i< prices.size();i++ )
sum = max(sum, f1[i] + f2[i]);
return sum;
}
};
优化:可以对上述code稍微优化一下,maxX 和minX array 并不需要,只要保留一个变量mini和maxX即可,不过由于f1和f2 的存在,空间复杂度还是O(n)
class Solution {
public:
int maxProfit(vector<int> &prices) {
if (prices.size() == )
return ;
vector<int> f1(prices.size());
vector<int> f2(prices.size());
int mini = prices[];
f1[] = ;
for(int i = ; i< prices.size();i++ )
{
f1[i] = max(f1[i-],prices[i]-mini);
mini = min(mini, prices[i]);
}
int maxi = prices[prices.size()-];
f2[prices.size()-] = ;
for(int i = prices.size() -; i >=; i-- )
{
f2[i] = max(f2[i+],maxi - prices[i]);
maxi = max(maxi, prices[i]);
}
int sum = ;
for(int i = ; i< prices.size();i++ )
sum = max(sum, f1[i] + f2[i]);
return sum;
}
};
[LeetCode] Best Time to Buy and Sell Stock III的更多相关文章
- LeetCode: Best Time to Buy and Sell Stock III 解题报告
Best Time to Buy and Sell Stock IIIQuestion SolutionSay you have an array for which the ith element ...
- [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 ...
- LeetCode: Best Time to Buy and Sell Stock III [123]
[称号] Say you have an array for which the ith element is the price of a given stock on day i. Design ...
- [Leetcode] Best time to buy and sell stock iii 买卖股票的最佳时机
Say you have an array for which the i th element is the price of a given stock on day i. Design an a ...
- [leetcode]Best Time to Buy and Sell Stock III @ Python
原题地址:https://oj.leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/ 题意: Say you have an array ...
- leetcode -- Best Time to Buy and Sell Stock III TODO
Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...
- LeetCode——Best Time to Buy and Sell Stock III
Description: Say you have an array for which the ith element is the price of a given stock on day i. ...
- LeetCode——Best Time to Buy and Sell Stock III (股票买卖时机问题3)
问题: Say you have an array for which the ith element is the price of a given stock on day i. Design a ...
- LeetCode OJ--Best Time to Buy and Sell Stock III
http://oj.leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/ 这三道题,很好的进阶.1题简单处理,2题使用贪心,3题使用动态 ...
随机推荐
- 将Html文档整理为规范XML文档
有多种方式可以在.NET 平台进行HTML文件解析.数据提取,其中最简单.稳妥的办法是先使用工具将Html文档整理成XML文档,再通过XML Dom模型或XPath灵活地进行数据处理.SGML便是一个 ...
- textfield控制光标开始位置
// UIView *paddingView1 = [[UIView alloc] initWithFrame:CGRectMake(0, 64, self.view.frame.size.wi ...
- 如何把apk编译时间和最后次git commit的sha值,写入到app中
需求背景:我们修复Bug的时候,频繁提交APK包,导致测试同学搞不清哪个包才是最新的 比如一个版本3.0.1,我们可能后续基于这个版本陆续提交了好几个修复包 同时,如果服务端ip地址能在界面上配置的话 ...
- setTimeout 0秒
我们通常知道常用setTimeout 0秒来解决动画或者一些效果的延迟问题:众所周知js是单线程,用0秒能把要执行的任务从队列中提出来.其实我也不太懂 有这个问题alert(1);setTimeout ...
- [bzoj 1026]windy数(数位DP)
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1026 分析: 简单的数位DP啦 f[i][j]表示数字有i位,最高位的数值为j的windy数总 ...
- 【web必知必会】—— DOM:四个常用的方法
终于开始复习DOM的知识了,这一阵忙乎论文,基本都没好好看技术的书. 记得去年实习的时候,才开始真正的接触前端,发现原来JS可以使用的如此灵活. 说起DOM就不得不提起javascript的组成了,j ...
- jsonp与跨域
<script>标签的src属性并不被同源策略所约束,所以可以获取任何服务器上脚本并执行. JSONP是JSON with Padding的略称.它是一个非官方的协议,它允许在服务器端集成 ...
- log4j1 插入mysql
做任务需要用到这样的需求: 使用log4j 1.2进行日志管理. 将日志输出到mysql中 系统数据库表利用脚本每日生成一张,插入系统运行时特定的表中. 实现方法 properties(放在项目根目录 ...
- Ibatis的类型处理器TypeHandler解析
Ibatis允许用户像在hibernate中一样定义自己的类型,但是,用户自定义类型需要与数据库中的字段类型进行对应.它的处理方法是允许我们扩展TypeHandler.Ibatis框架在处理该数据类型 ...
- Linux中使用crontab命令定时执行shell脚本或其他Linux命令
使用crontab你可以在指定的时间执行一个shell脚本或者一系列Linux命令.例如系统管理员安排一个备份任务使其每天都运行 如何往 cron 中添加一个作业? # crontab –e0 5 * ...