【LeetCode】Best Time to Buy and Sell Stock 程序员炒股 part.2
来源:互联网 发布:红蓝光美容仪 知乎 编辑:程序博客网 时间:2024/05/16 10:24
【题目】
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.
一个数组price[i]表示第i天股票的价格,你可以操作两次(进行两次买卖),求最大获利。
【解析】
又一道动态规划。
假设刚开始我一毛钱都没有。
第i天可以进行的操作有4种:
1. 前i天只进行一次买进操作。profit_Buy1Sell0[i]
毫无疑问这是亏本的。如果买进第i天的股票,则盈利为-price[i],如果不买第i天的股票,那么去“前i-1天只进行一次买进操作”的过程里去找对应的值profit_Buy1Sell0[i-1],比较-price[i]和profit_Buy1Sell0[i-1]的大小取较大者,即为该操作下的最大盈利(最小亏损),赋值给profit_Buy1Sell0[i]
即,
profit_Buy1Sell0[i] = max ( -price[i] , profit_Buy1Sell0[i-1] )
2. 前i天进行一次买进和一次卖出操作。profit_Buy1Sell1[i]
在第i天的时候,我有两种选择:
第一种,卖出当天的股票,前提是我手上已经有一支股票了,那么我就去“前i-1天只进行一次买进操作”的过程里取找对应的值profit_Buy1Sell0[i-1],接下来将前i-1天买到的那只股票卖掉,那么盈利为—— profit_Buy1Sell0[i-1] + price[i]
第二种,当天不进行操作,也就是说在前i-1天已经进行了一次买进和一次卖出的操作了。则此时盈利为:profit_Buy1Sell1[i-1]
比较以上两种操作方法,取最大值赋给profit_Buy1Sell1[i]
即,
profit_Buy1Sell1[i] = max ( profit_Buy1Sell0[i-1] + price[i] , profit_Buy1Sell1[i-1] )
3. 前i天进行两次买进和一次卖出操作。profit_Buy2Sell1[i]
同样到了第i天,我有两种两种选择:
买进当天的股票,或者不买。
同上,若买进,前i-1天就进行了一次买进和一次卖出,去找profit_Buy1Sell1[i-1],在减掉购买当天股票的成本,即为profit_Buy1Sell1[i-1]-price[i]。
若不买,则前i-1天已经完成了两次买进一次卖出的操作,去找profit_Buy2Sell1[i-1]。
取两者最大值赋给profit_Buy2Sell1[i]
即,
profit_Buy2Sell1[i] = max ( profit_Buy1Sell1[i-1]-price[i] , profit_Buy2Sell1[i-1] )
4. 前i天进行两次买进和两次次卖出操作。profit_Buy2Sell2[i]
到了这一步思路应当逐渐清晰,两种选择:
卖出当天股票,获益为profit_Buy2Sell1[i-1] + price[i]
不卖当天股票,获益为前i-1天进行两买两卖的获益,即profit_Buy2Sell2[i-1]
取两者最大值,即为:
profit_Buy2Sell2[i] = max ( profit_Buy2Sell1[i-1] + price[i] , profit_Buy2Sell2[i-1] )
最后,比较profit_Buy1Sell1[i] 和 profit_Buy2Sell2[i] ,输出两者的较大值。
注:profit_Buy1Sell1[i] 若较大,是否是只进行了一次操作,从而与题意不符???
从讨论的结果看来,此题应该是考虑了当天买当天卖的这种情况,也合情合理,买卖一次就能利益最大化,为什么还要乱操作一通。。。
上述四种操作,编程的时候可以建立4个不同的数组,从0到i遍历price数组,将4个数组逐个填入对应数。
为减少空间复杂度,可以用current[0-3]和next[0-3]来保存当日操作的盈利数据。
【程序】
理解版:
class Solution {public: int maxProfit(vector<int>& prices) { int len = prices.size(); int profit_Buy1Sell0[len+1]={INT_MIN}; int profit_Buy1Sell1[len+1]={0}; int profit_Buy2Sell1[len+1]={INT_MIN}; int profit_Buy2Sell2[len+1]={0}; for(int i = 0; i<len; i++) { profit_Buy1Sell0[i+1] = max(profit_Buy1Sell0[i], -prices[i]); profit_Buy1Sell1[i+1] = max(profit_Buy1Sell0[i] + prices[i] , profit_Buy1Sell1[i]); profit_Buy2Sell1[i+1] = max(profit_Buy1Sell1[i] - prices[i] , profit_Buy2Sell1[i]); profit_Buy2Sell2[i+1] = max(profit_Buy2Sell1[i] + prices[i] , profit_Buy2Sell2[i]); } return max(profit_Buy1Sell1[len],profit_Buy2Sell2[len]); }};
优化之后:
class Solution {public: int maxProfit(vector<int>& prices) { int states[2][4] = {INT_MIN, 0, INT_MIN, 0}; // 0: 1 buy, 1: one buy/sell, 2: 2 buys/1 sell, 3, 2 buys/sells int len = prices.size(), i, cur = 0, next =1; for(i=0; i<len; ++i) { states[next][0] = max(states[cur][0], -prices[i]); states[next][1] = max(states[cur][1], states[cur][0]+prices[i]); states[next][2] = max(states[cur][2], states[cur][1]-prices[i]); states[next][3] = max(states[cur][3], states[cur][2]+prices[i]); swap(next, cur); } return max(states[cur][1], states[cur][3]); }
- 【LeetCode】Best Time to Buy and Sell Stock 程序员炒股 part.2
- 【LeetCode】Best Time to Buy and Sell Stock 程序员炒股 part.1
- 【LeetCode】Best Time to Buy and Sell Stock 程序员炒股 part.3
- Leetcode Best Time to Buy and Sell Stock 2
- 【LeetCode】Best Time to Buy and Sell Stock & Best Time to Buy and Sell Stock
- [LeetCode] [LeetCode]Best Time to Buy and Sell Stock
- 【LeetCode with Python】 Best Time to Buy and Sell Stock
- [LeetCode]Best Time to Buy and Sell Stock
- [LeetCode]Best Time to Buy and Sell Stock II
- LeetCode Best Time to Buy and Sell Stock
- LeetCode Best Time to Buy and Sell Stock II
- LeetCode Best Time to Buy and Sell Stock III
- Leetcode: Best time to buy and sell a stock I
- Leetcode: Best Time to Buy and Sell Stock II
- LeetCode Best Time to Buy and Sell Stock III
- [Leetcode] Best Time to Buy and Sell Stock
- [Leetcode] Best Time to Buy and Sell Stock II
- [Leetcode] Best Time to Buy and Sell Stock III
- 最大乘积或和子序列
- 关于dp转px
- mysql添加列,修改列,删除列
- Unity3D学习日记(三)贝塞尔曲线
- linux使用心得
- 【LeetCode】Best Time to Buy and Sell Stock 程序员炒股 part.2
- 第一次博客的作业解析
- android中的CheckBox改变背景图片后图片显示大小不正确的问题
- 【linux学习笔记】在ubuntu下使用QT Cmake支持C++11
- synchronized与static synchronized 的区别
- STL中全排列函数 next_permutation
- 游戏引擎
- QT学习之 信号与槽机制
- 训练2 8题