多种买卖股票算法解决方案
1、leetcode121
给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。
你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。
来源:力扣(LeetCode)
class Solution { public int maxProfit(int[] prices) { int[][] dp = new int[prices.length][2]; dp[0][0]=-prices[0];//买入状态 1代表卖出状态 for(int i = 1;i<prices.length;i++){ dp[i][0]=Math.max(dp[i-1][0],-prices[i]); dp[i][1]=Math.max(dp[i-1][0]+prices[i],dp[i-1][1]); } return dp[prices.length-1][1]; } }
思路:每天存在两种状态,第一种持有状态,第二种是卖出状态。
第一种状态来源于前一天买入的状态,或者是当天才买入的状态
第二种状态来源于前一天卖出状态保持到今天,或者今天才卖出。
dp[i][j],i代表是第几天,j是两种状态,分别是买入或者持有的最大利益值。
Leetcode 122 买卖股票的最佳时机 II
自己的解法:
public int maxProfit(int[] prices) { int[][] dp = new int[prices.length][2]; dp[0][0]=-prices[0]; int res = 0; for(int i = 1;i<prices.length;i++){ dp[i][0]=Math.max(dp[i-1][0],-prices[i]);//保持持有,或者今天持有 dp[i][1]=Math.max(dp[i-1][1],dp[i-1][0]+prices[i]);//保持卖出,或者今天才卖出。 if(dp[i][1]>0){ res+=dp[i][1]; dp[i][0]=-prices[i]; dp[i][1]=0; } } return res; }
算出每一天利润是否大于0,大于0我就卖出,累加利润。
官方解法:
public int maxProfit(int[] prices) { int[][] dp = new int[prices.length][2]; dp[0][0]=-prices[0];//持有 dp[0][1]=0;//不持有 for(int i = 1;i<prices.length;i++){ dp[i][0]=Math.max(dp[i-1][0],dp[i-1][1]-prices[i]);//持有 保持昨天的持有状态,或者卖出状态减去购买今天的股票。 dp[i][1]=Math.max(dp[i-1][1],dp[i][0]+prices[i]); //两个状态的转移,都是来自上一个状态,或者上一个合法状态到当前这个状态。 } return dp[prices.length-1][1]; }
Leetcode 123 买卖股票的最佳时机 III
public int maxProfit(int[] prices) { int[][] dp = new int[prices.length][5]; dp[0][1] = -prices[0];//第一次买入 dp[0][3] = -prices[0];//第二次买入 依赖与第一次买入,所以 for (int i = 1; i < prices.length; i++) { dp[i][0] = dp[i - 1][0]; dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i]);//当前持有 dp[i][2] = Math.max(dp[i - 1][2], dp[i - 1][1] + prices[i]);//当前卖出 dp[i][3] = Math.max(dp[i - 1][3], dp[i - 1][2] - prices[i]);//第二次买入 dp[i][4] = Math.max(dp[i - 1][4], dp[i - 1][3] + prices[i]);//第二次卖出 } return dp[prices.length - 1][4]; }
//
第二次买入依赖于第一次卖出的状态,其实相当于第0天第一次买入了,第一次卖出了,然后在买入一次(第二次买入),那么现在手头上没有现金,只要买入,现金就做相应的减少。
所以第二次买入操作,初始化为:dp[0][3] = -prices[0];
同理第二次卖出初始化dp[0][4] = 0;
设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票) 同一天买了又卖,就能解决上面的初始化问题。
leetcode 188 买卖股票的最佳时机 IV
public int maxProfit(int k, int[] prices) { if(prices.length==0){ return 0; } int[][][] dp = new int[prices.length][k+1][2]; for(int i = 0;i<=k;i++){ //初始化 0代表是买入状态,1是代表卖出状态 dp[0][i][0]=-prices[0]; } for(int i = 1;i<prices.length;i++){ for(int j = 1;j<=k;j++){ dp[i][j][0]=Math.max(dp[i-1][j][0],dp[i-1][j-1][1]-prices[i]); //当前是今天买入状态,或者昨天未持有,就要j-1笔 dp[i][j][1]=Math.max(dp[i-1][j][1],dp[i-1][j][0]+prices[i]); //保持卖出,从上一个买入状态卖出。 } } return dp[prices.length-1][k][1]; }
leetcode 最佳买卖股票时机含冷冻期
int n = prices.length; if (n == 0) { return 0; } //状态一 0 持有股票 (第一种是保持买入,第二种是冷冻期,保持卖出) 保持买入该状态转移过来的,第二种冷冻期后买入第四种状态,冷冻期过来,或者状态2中保持卖出。 //状态二 1 卖出股票:1、前一天就是状态 2 昨天是冷冻期 该状态转移过来的,和状态4转移过来的。 //状态三 2 卖出股票,今天卖股票 //状态四 3 冷冻期今天 int[][] dp = new int[prices.length][4]; dp[0][0] = -prices[0];//持有股票 for (int i = 1; i < n; i++) { //持有股票,保持昨天的持有,今天购买 前一天不可能刚刚卖出,如果卖出就是冷冻期 dp[i][0]=Math.max(dp[i-1][0],Math.max(dp[i-1][1],dp[i-1][3])-prices[i]); dp[i][1]=Math.max(dp[i-1][1],dp[i-1][3]); dp[i][2]=dp[i-1][0]+prices[i]; dp[i][3]=dp[i-1][2]; } return Math.max(Math.max(dp[prices.length-1][0],dp[prices.length-1][1]),Math.max(dp[prices.length-1][2],dp[prices.length-1][3])); }
leetcode 714. 买卖股票的最佳时机含手续费
public int maxProfit(int[] prices, int fee) { int[][] dp = new int[prices.length][2]; dp[0][0] = -prices[0]; //买入 for(int i = 1;i<prices.length;i++){ dp[i][0]=Math.max(dp[i-1][0],dp[i-1][1]-prices[i]); dp[i][1]=Math.max(dp[i-1][1],dp[i-1][0]+prices[i]-fee); } return dp[prices.length - 1][1]; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人