leetcode 123. Best Time to Buy and Sell Stock III 最大k次字段和 + DP
来源:互联网 发布:autoit python 编辑:程序博客网 时间:2024/06/07 02:19
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).
这个要求可以最多做两次交易,来实现最大利益化。最直接的方法就是使用两次最大子段和,但是会超时。
网上看到了这样的解决方法,感觉很棒:这解法的核心是假设手上最开始只有0元钱,那么如果买入股票的价格为price,手上的钱需要减去这个price,如果卖出股票的价格为price,手上的钱需要加上这个price。
Buy1[i]表示前i天做第一笔交易买入股票后剩下的最多的钱
Sell1[i]表示前i天做第一笔交易卖出股票后剩下的最多的钱;
Buy2[i]表示前i天做第二笔交易买入股票后剩下的最多的钱;
Sell2[i]表示前i天做第二笔交易卖出股票后剩下的最多的钱;
那么有如下的递推公式:
Sell2[i]=max{Sell2[i-1],Buy2[i-1]+prices[i]}
Buy2[i]=max{Buy2[i-1],Sell[i-1]-prices[i]}
Sell1[i]=max{Sell[i-1],Buy1[i-1]+prices[i]}
Buy1[i]=max{Buy[i-1],-prices[i]}
可以发现上面四个状态都是只与前一个状态有关,所以可以不使用数组而是使用变量来存储即可。
建议和leetcode 188. Best Time to Buy and Sell Stock IV 最大子段和 、leetcode 123. Best Time to Buy and Sell Stock III 最大k次字段和 + DP 、leetcode 122. Best Time to Buy and Sell Stock II 最大子段和 + DP 、leetcode 121. Best Time to Buy and Sell Stock 最大字段和问题 + DP 、leetcode 714. Best Time to Buy and Sell Stock with Transaction Fee 动态规划DP一起学习。
在下面的代码中我写了三种解决方法:
1)两次使用最大子段和;
2)使用上述方法;
3)实现了最多n次交易的方法。
代码如下:
import java.util.Arrays;/* * 算法导论说这个问题可以转华为最大字段和的问题 * */public class Solution { /* * 第二种解法的核心是假设手上最开始只有0元钱,那么如果买入股票的价格为price,手上的钱需要减去这个price, * 如果卖出股票的价格为price,手上的钱需要加上这个price。 * Buy1[i]表示前i天做第一笔交易买入股票后剩下的最多的钱 * Sell1[i]表示前i天做第一笔交易卖出股票后剩下的最多的钱; * Buy2[i]表示前i天做第二笔交易买入股票后剩下的最多的钱; * Sell2[i]表示前i天做第二笔交易卖出股票后剩下的最多的钱; * * 那么Sell2[i]=max{Sell2[i-1],Buy2[i-1]+prices[i]} * Buy2[i]=max{Buy2[i-1],Sell[i-1]-prices[i]} * Sell1[i]=max{Sell[i-1],Buy1[i-1]+prices[i]} * Buy1[i]=max{Buy[i-1],-prices[i]} * 可以发现上面四个状态都是只与前一个状态有关, * 所以可以不使用数组而是使用变量来存储即可。 * * */ public int maxProfit(int[] prices) { if(prices==null || prices.length<=0) return 0; int buy1=Integer.MIN_VALUE,buy2=Integer.MIN_VALUE; int sell1=0,sell2=0; for(int i=0;i<prices.length;i++) { buy1=Math.max(buy1, -prices[i]); sell1=Math.max(sell1, buy1+prices[i]); buy2=Math.max(buy2, sell1-prices[i]); sell2=Math.max(sell2, buy2+prices[i]); } return sell2; } /* * 这里可以求解最多n个交易的最大利益值 * */ public int maxProfit11111(int[] prices) { if(prices==null || prices.length<=0) return 0; return maxProfitByNTransactions(prices, 2); } public int maxProfitByNTransactions(int[] prices,int n) { if(prices==null || prices.length<=0) return 0; int[] buy=new int[n]; Arrays.fill(buy, Integer.MIN_VALUE); int[] sell=new int[n]; Arrays.fill(sell, 0); for(int i=0;i<prices.length;i++) { buy[0]=Math.max(buy[0], -prices[i]); sell[0]=Math.max(sell[0], buy[0]+prices[i]); for(int j=1;j<n;j++) { buy[j]=Math.max(buy[j],sell[j-1]-prices[i]); sell[j]=Math.max(sell[j], buy[j]+prices[i]); } } return sell[n-1]; } /* * 这个方法超时,我是考虑做两次最大子段和来做的,会超时也不奇怪了 * * 不过这是我能想到的最直接的方法 * * */ public int maxProfitByTwiceDP(int[] prices) { if(prices==null || prices.length<=1) return 0; int []num=new int[prices.length-1]; for(int i=1;i<prices.length;i++) num[i-1]=prices[i]-prices[i-1]; int sum=0; for(int i=0;i<num.length;i++) sum=Math.max(sum, getMaxSum(num, 0, i)+ getMaxSum(num, i+1, num.length-1) ); return sum; } /* * 动态规划求解最大子段和 * */ int getMaxSum(int[] num,int beg,int end) { int sum=0,dp=0; for (int i = beg; i <=end; i++) { if(dp>0) dp=dp+num[i]; else dp=num[i]; sum=Math.max(dp, sum); } return sum; }}
下面是C++的做法,这道题是一个很不错的做法,我是没想出来这么做,这道题很值得学习
代码如下:
#include <iostream>#include <vector>#include <algorithm>#include <climits>using namespace std;class Solution {public: int maxProfit(vector<int>& p) { if (p.size() <= 1) return 0; else return KTransactions(p, 2); } int KTransactions(vector<int> p, int k) { vector<int> buy(k,numeric_limits<int>::min()); vector<int> sell(k, 0); for (int i = 0; i < p.size(); i++) { buy[0] = max(buy[0], -p[i]); sell[0] = max(sell[0],buy[0]+p[i]); for (int j = 1; j < k; j++) { buy[j] = max(buy[j], sell[j-1]-p[i]); sell[j] = max(sell[j], buy[j] + p[i]); } } return sell[k - 1]; }};
- leetcode 123. Best Time to Buy and Sell Stock III 最大k次字段和 + DP
- leetcode 121. Best Time to Buy and Sell Stock 最大字段和问题 + DP
- 【Leetcode】Best Time to Buy and Sell Stock III (DP)
- [leetcode][DP] Best Time to Buy and Sell Stock III
- [leetcode][DP] Best Time to Buy and Sell Stock III
- LeetCode Best Time to Buy and Sell Stock III(dp)
- LeetCode 123. Best Time to Buy and Sell Stock III
- [Leetcode]123.Best Time to Buy and Sell Stock III
- [Leetcode] 123. Best Time to Buy and Sell Stock III
- [leetcode] 123.Best Time to Buy and Sell Stock III
- 【leetcode】123. Best Time to Buy and Sell Stock III
- [leetcode] 123. Best Time to Buy and Sell Stock III
- leetcode 123. Best Time to Buy and Sell Stock III
- leetcode 123. Best Time to Buy and Sell Stock III
- [LeetCode] 123. Best Time to Buy and Sell Stock III
- Leetcode 123. Best Time to Buy and Sell Stock III
- 【leetcode】123. Best Time to Buy and Sell Stock III
- LeetCode 123. Best Time to Buy and Sell Stock III
- 【趣发现】区块链和云计算类型撞名了?
- 智链ChainNova携手IBM推出端到端区块链联合解决方案
- 遮罩板,蒙板【前端组件】
- Strom官网信息
- 百炼+日期转换+注意数组不能越界,免得re
- leetcode 123. Best Time to Buy and Sell Stock III 最大k次字段和 + DP
- css弹性动画效果
- 【牛客 题库】 char型变量值为1个字节长度,并从右侧开始运算 || abs返回值 || 函数模板
- 北大金融科技研究中心成立 智链 CEO 董宁担任中心主任
- java和安卓SMB创建文件夹
- 序列化(Serialization)的使用
- http状态码及详细解释
- [Android] Android Studio 导入 Samples 的另外一种方法
- 技术盛会多烧脑? Hyperledger北京Meetup落幕全球创新社区