Best Time to Buy and Sell Stock IV(DP解法,o(kn)时间,o(k)空间)
来源:互联网 发布:网络播放器安装电视猫 编辑:程序博客网 时间:2024/05/16 10:31
Leetcode 上Best Time to Buy and Sell Stock IV解题思路:
此解法主要参考http://blog.csdn.net/linhuanmars/article/details/23236995#cpp上的思路, 但是博主的递归式不是很好理解,因此加上自己的理解,希望对后来者有所帮助, 第一次这么认真的写博客,如发现问题或者理解错误,欢迎批评指正,谢谢!
DP解法:
假设prices(0) 为第 1 天, 建立两个数组,一个为local[i][j] (从第 1 到 第 i天交易 j 次,并且最后一次卖出为第 i 天的最大利润), 另一个为 global[i][j] (从第 1 到第 i 天交易 j 次的最大利润)。可建立如下递归式:
global[i][j]=max(local[i][j],global[i-1][j]);
global[i][j] 可以分成两种情况:
1. 最后一次交易为最后一天,最大利润则为 local[i][j];
2. 最后一次交易不是最后一天, 因此所有 j 次交易在 第 1 到第 i - 1 天内完成,因此为global[i - 1][j]。
取两者中较大者。
同时需要DP计算local 数组,建立如下递归式(diff = prices[i] - prices[i - 1]):
local[i][j]=max(global[i-1][j-1]+max(diff,0), local[i-1][j]+diff);
同样,local[i][j] 的计算分为两种情况:
1. 最后一次买的时间为第 i - 1 或者第 i 天, 要保证local[i][j] 最大,则第i - 1 天以前买卖的 j - 1 次必须有最大利润,同时,如果diff > 0, 则最后一次的利润取diff, 如果diff < 0, 则取 0, 即第 i 天买, 第 i 天卖。
2. 最后一次买的时间为第 i - 1 天以前,同时最后一次卖必须为第 i 天(local 数组的定义), 同时可以分为两部分利润, 第一部分为前i - 1天的利润和第 i - 1 天到第 i 天的利润。要保证local[i][j] 最大, 则必须保证第一部分利润为最大,第二部分利润是不变的,为diff, 第一部分利润的最大值就相当于local[i - 1][j]。
观察上面数组,递归式中计算第 i 天时实际使用的数据只有第 i - 1天的数据, 因此可以使用一维数组来代替, 建立递归式如下:
local[j] = max(global[j - 1] + max(diff, 0), local[j] + diff);global[j] = max(local[j], global[j]);
这里存在一个小技巧,求第 local[i] 和 global[i] 时,采用从上往下循环,因此递归式中的第一个递归式中 等式右边的global[j - 1] 即为二维数组的global[i - 1][j - 1], local[j] 对应local[i - 1][j], 第二个式中等式右边的local[i]因为在第一个式中已经算出新值, 因此对应local[i][j], 而global[j] 对应 global[i - 1][j].
源代码如下(这里需要考虑 k > prices.size()的情况, 因为对于 n = prices.size() 最多只能产生 n - 1 次能产生利润的交易, 即在不同天内买卖才有可能利润, 因此当交易次数大于n时, 则和 Best Time to Buy and Sell Stock II 一样):
class Solution {public:int maxProfitII(vector<int>& prices) { int maxSum = 0, currSum = 0, tmp; for(int i = 1; i < prices.size(); ++i) { tmp = currSum; currSum += prices[i] - prices[i - 1]; if(currSum < tmp) { maxSum += tmp; currSum = 0; } } if(currSum > 0) maxSum += currSum; return maxSum; } int maxProfit(int k, vector<int>& prices) { if(k < 0 || prices.empty()) return 0; int n = prices.size(); if(k > n) return maxProfitII(prices); vector<int> global(k + 1, 0), local(k + 1, 0); int diff; for(int i = 1; i < n; ++i) { diff = prices[i] - prices[i - 1]; for(int j = k; j >= 1; --j) { local[j] = max(global[j - 1] + max(diff, 0), local[j] + diff); global[j] = max(local[j], global[j]); } } return global[k]; }};
- Best Time to Buy and Sell Stock IV(DP解法,o(kn)时间,o(k)空间)
- 【LeetCode】Best Time to Buy and Sell Stock IV 动态规划dp解法(C++)
- LeerCode 123 Best Time to Buy and Sell Stock III之O(n)解法
- Best Time to Buy and Sell Stock IV(未完成)
- LeetCode--Best Time to Buy and Sell Stock IV(DP + 滚动数组)
- leetcode 第188题,我的解法,Best Time to Buy and Sell Stock IV
- 递推思想的美妙 Best Time to Buy and Sell Stock I, II, III O(n) 解法
- Best Time to Buy and Sell Stock IV
- [LeetCode] Best Time to Buy and Sell Stock IV
- Best Time to Buy and Sell Stock IV
- Best Time to Buy and Sell Stock IV
- Best Time to Buy and Sell Stock IV
- leetcode: Best Time to Buy and Sell Stock IV
- LeetCode(188) Best Time to Buy and Sell Stock IV
- Best Time to Buy and Sell Stock IV
- Best Time to Buy and Sell Stock IV -- leetcode
- Best Time to Buy and Sell Stock IV
- 【动态规划】Best Time to Buy and Sell Stock IV
- Failed to read schema document 'http://code.alibabatech.com/schema/dubbo/dubbo.xsd'问题解决方法
- 《swift2.0 官方教程中文版》 第3章-02类型
- mysql 5.7.10 表空间及多分区数据库
- spring框架(IOC)的理解
- Ubuntu15.10 禁用自带的nouveau驱动(安装NVIDIA驱动)
- Best Time to Buy and Sell Stock IV(DP解法,o(kn)时间,o(k)空间)
- 使用NSURLSession程序退出后继续下载
- 翻书动画实现
- android 实现应用内语言切换
- Myeclipse 配置了Tomcat内存但是不生效
- Java 编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串
- 围绕中心点进行旋转
- Egret)引擎工作原理
- 每天学点Python之collections