Best Time to Buy and Sell Stock
来源:互联网 发布:it人才培训机构 编辑:程序博客网 时间:2024/06/14 21:37
最近遇到一道题,数组表示当日股价,最多进行2次买卖,而且不能连续买,只能买卖买卖。问能赚到的最大值。
知道这是一道类型题,但是我想自己独立解决。不过能力有限,最后还是参考了网络中的大牛解法。这里做一下总结。
参考推库, 一个神奇的网站。
http://www.tuicool.com/articles/rMJZj2
能够感到这是一道动态规划的题,分成2部分,然后求和的最大值,但是如何对一部分求一次买卖所能获得的最大值呢?
开始考虑记录相邻两项的差,然后看看,当时没有想到转化为,相邻差数组的连续和的最大值,所以没能找到答案。
找到最低点,一次计算每一点到最低点的差,然后求最大。
这里需要注意,并不是求最高点和最低点的差。因为最高点可能在最低点的前面。
仔细想一想,这也是一个动态规划的问题,动态的找到相对最高点和最低点,然后比较找出最大。
这里,用low 来记录相对的最小值,每当有元素比low小,就更新相对最小值。
如果,比low 大,那么计算差值和最大值比较。
现在我们知道了如何从数组中,一次买卖能获得的最大值。
这里需要对 MaxProfitInStock(int *a, int length) 做一点儿小小改动。
求 a[start~endL]中的买卖最大值。
那么,我们就可以开始进行动态划分,然后找到两部分最大值和的最大值。
所以整体是 O(n^2)。
思路2.
既然我们能在O(n)的时间求出 a[start ~ end]中差值的最大值,
那不妨记录一下 a[0 ~ i] 和 a[i ~ length-1]的最大值,在求求和的最大值。
first[i] 表示 a[0 ~ i] 的最大值
last[i] 表示 b[i ~ length-1]的最大值
那么整体的最大值 就是
max(first[i] + last[i]) 0 <= i <= length-1
此时,整体的复杂度为 O(n)
补充,我自己开始的那个想法。
先记录相邻两项差,然后求连续和的最大值。
知道这是一道类型题,但是我想自己独立解决。不过能力有限,最后还是参考了网络中的大牛解法。这里做一下总结。
参考推库, 一个神奇的网站。
http://www.tuicool.com/articles/rMJZj2
能够感到这是一道动态规划的题,分成2部分,然后求和的最大值,但是如何对一部分求一次买卖所能获得的最大值呢?
开始考虑记录相邻两项的差,然后看看,当时没有想到转化为,相邻差数组的连续和的最大值,所以没能找到答案。
找到最低点,一次计算每一点到最低点的差,然后求最大。
这里需要注意,并不是求最高点和最低点的差。因为最高点可能在最低点的前面。
仔细想一想,这也是一个动态规划的问题,动态的找到相对最高点和最低点,然后比较找出最大。
这里,用low 来记录相对的最小值,每当有元素比low小,就更新相对最小值。
如果,比low 大,那么计算差值和最大值比较。
int MaxProfitInStock(int *a, int length){ bool isArrayVaild(int *, int); if(!isArrayVaild(a, length)) return 0; int Max, low; //int cur = a[0]; low = a[0]; Max = 0; int i; for(i = 1; i < length; ++i) { if(a[i] < low) low = a[i]; else if(a[i] - low > Max) Max = a[i] - low; } return Max;}
现在我们知道了如何从数组中,一次买卖能获得的最大值。
这里需要对 MaxProfitInStock(int *a, int length) 做一点儿小小改动。
求 a[start~endL]中的买卖最大值。
那么,我们就可以开始进行动态划分,然后找到两部分最大值和的最大值。
int MaxProfitInStock_DP(int *a, int start, int endL){ if(NULL == a || start >= endL) return 0; int Max, low; //int cur = a[0]; low = a[start]; Max = 0; int i; for(i = start; i <= endL; ++i) { if(a[i] < low) low = a[i]; else if(a[i] - low > Max) Max = a[i] - low; } return Max;}int MaxProfitInStock_maxBuy2_DP(int *a, int length){ if(!isArrayVaild(a, length)) return 0; int Max = 0; int i, tmp; for(i = 0; i < length; ++i) { tmp = MaxProfitInStock_DP(a, 0, i) + MaxProfitInStock_DP(a, i+1, length-1); if(tmp > Max) Max = tmp; } return Max;}
所以整体是 O(n^2)。
思路2.
既然我们能在O(n)的时间求出 a[start ~ end]中差值的最大值,
那不妨记录一下 a[0 ~ i] 和 a[i ~ length-1]的最大值,在求求和的最大值。
first[i] 表示 a[0 ~ i] 的最大值
last[i] 表示 b[i ~ length-1]的最大值
那么整体的最大值 就是
max(first[i] + last[i]) 0 <= i <= length-1
此时,整体的复杂度为 O(n)
int MaxProfitInStock_maxBuy2_DP_1(int *a, int length){ if(!isArrayVaild(a, length)) return 0; int *first, *last; first = new int[length]; last = new int[length]; first[0] = 0; last[length - 1] = 0; int Max = 0; int cur, i; int low, high; low = a[0]; for(i = 1; i < length; ++i) { if(a[i] < low) low = a[i]; else if(a[i] - low > Max) Max = a[i] - low; first[i] = Max; } Max = 0; high = a[length - 1]; for(i = length - 2; i >= 0; --i) { if(a[i] > high) high = a[i]; else if(high - a[i] > Max) Max = high - a[i]; last[i] = Max; } Max = first[0] + last[0]; for(i = 1; i < length; ++i) { if(first[i] + last[i] > Max) Max = first[i] + last[i]; } delete[] first; delete[] last; first = last = NULL; return Max;}
补充,我自己开始的那个想法。
先记录相邻两项差,然后求连续和的最大值。
int MaxProfitInStock_Mine(int *a, int length){ if(!isArrayVaild(a, length) || (1 == length)) return 0; int chaNum = length - 1; int *cha = new int[chaNum]; int i; for(i = 0; i < chaNum; ++i) { cha[i] = a[i + 1] - a[i]; } int Max = 0; int curSum = 0; //int start = -1; for(i = 0; i < chaNum; ++i) { curSum += cha[i]; if(curSum > Max) Max = curSum; if(curSum < 0) { curSum = 0; } } delete[] cha; cha = NULL; return Max;}
0 0
- Best Time to Buy and Sell Stock
- Best Time to Buy and Sell Stock
- Best Time to Buy and Sell Stock
- Best Time to Buy and Sell Stock
- Best Time to Buy and Sell Stock
- Best Time to Buy and Sell Stock
- Best Time to Buy and Sell Stock
- Best Time to Buy and Sell Stock
- Best Time to Buy and Sell Stock
- Best Time To Buy and Sell Stock
- Best Time to Buy and Sell Stock
- Best Time to Buy and Sell Stock
- Best Time to Buy and Sell Stock
- Best Time to Buy and Sell Stock
- Best Time to Buy and Sell Stock
- Best Time to Buy and Sell Stock
- Best Time to Buy and Sell Stock
- Best Time to Buy and Sell Stock
- 动态规划之——拦截导弹(nyoj79)
- WebView与JS交互【中级】
- 系统加大硬盘容量方法
- C++在继承的构造函数和析构函数
- UVA - 571 - Jugs (数论 - 经典倒水问题)
- Best Time to Buy and Sell Stock
- 使用 CSS3 中的伪类渲染表格
- union中大小
- Factorial Trailing Zeroes - LeetCode 172
- 黑马程序员——IO流(下篇)
- Linux程序设计(Linux shell编程的例子:生成网页文件)
- 关于STM32在MDK环境下的宏定义设置
- Simultaneous Localization and Mapping (SLAM)讲义1
- hdu5210 Delete