多种买卖股票算法解决方案

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];
    }
复制代码

 

posted @   雷雷提  阅读(124)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示