leetcode 股票系列 121, 122, 123, 309, 118,714(dp)

leetcode121 ez:
题目:一次交易(找出最大差值)
做法:最小值记录到目前为止的最小值,res记录到目前为止最大利润。遍历一遍找到最大值。

class Solution {
    public int maxProfit(int[] prices) {
        int min=Integer.MAX_VALUE;
        int res=0; 
        for(int i=0;i<prices.length;i++){   
            if(prices[i]<min) min=prices[i];
            res=Math.max((prices[i]-min),res);
        }
        return res;
    } 
}

leetcode122 ez:
题目:无数次交易
做法:遍历一次 累加所有差值。

class Solution {
    public int maxProfit(int[] prices) {
        int maxprofit = 0;
        for (int i = 1; i < prices.length; i++) {
            if (prices[i] > prices[i - 1])
                maxprofit += prices[i] - prices[i - 1];
        }
        return maxprofit;
    }
}

leetcode123 hard:
题目:最多两次
做法:
DP[i][j] 到第i天为止最大利润,[j] {0,1}记录有没有持股
状态转移方程:
DP[i,0]=Max{ DP[i-1,0] //不动 DP[i-1,1] +a[i]//卖
DP[i,1]=Max{ DP[i-1,1] //不动 DP[i-1,0] -a[i]//买

判断交易小于k次 再加一纬度

class Solution {
  public int maxProfit(int[] prices) {
    if (prices.length == 0) {
        return 0;
    }
int m= prices.length;
    int[][][] dp=new int[m+1][2][3];  
    for(int i=m-1;i>=0;i--){
        for(int j=1;j>=0;j--){
           for(int k=2;k>=0;k--){
               if(k==2&&j==0){
                   continue;
               }
               if(j==1){ //持仓
                   dp[i][j][k]=Math.max(prices[i]+dp[i+1][0][k],dp[i+1][1][k]); 
               }
              else if(j==0){//空仓
              dp[i][j][k] = Math.max(-prices[i] + dp[i+1][1][k+1],dp[i+1][0][k]);
               }
           } 
        }
    }    
 return dp[0][0][0];     
 }
}

leetcode 309. mid 最佳买卖股票时机含冷冻期

题目:卖出后需要冷冻一天
做法:dp[i][j] i 记录哪一天,j记录

class Solution {
    public int maxProfit(int[] prices) {
      if(prices.length<1) return 0;
    int[][] dp=new int[prices.length][3];
   dp[0][0]=0;
   dp[0][1]=-prices[0];
   dp[0][2]=0;
    for(int i=1;i<prices.length;i++){
            //第i天不持有股票的情况有两种
            //a.第i-1天也不持有股票
            //b.第i-1天是过渡期
        dp[i][0]=Math.max(dp[i-1][0],dp[i-1][2]);
            //第i天持有股票有两种情况
            //a.第i-1天也持有股票,第i天不操作,
            //b.第i-1天不持有股票,在第i天买入
        dp[i][1]=Math.max(dp[i-1][0]-prices[i],dp[i-1][1]);
        //第i天是冷冻期只有一种情况,第i-1天持有股票且卖出
        dp[i][2]=dp[i-1][1]+prices[i];
    }    
       //最后最大利润为最后一天,不持有股票或者进入冷冻期的情况
       return  Math.max(dp[prices.length-1][0],dp[prices.length-1][2]);
    }
}

leetcode188. 买卖股票的最佳时机 IV

题目:限定只能买卖k次
做法:同买卖两次

class Solution {
    public static int maxProfit(int k, int[] prices) {
        if (k > prices.length) {
            int temp = 0;
            for (int i = 0; i < prices.length - 1; i++) {
                if(prices[i+1]>prices[i])
                    temp += prices[i + 1] - prices[i];    
            }
            return temp;
        }
        if (prices.length == 0) {
        return 0;
    }
     int length= prices.length;
    int[][][] dp=new int[length+1][2][k+1];  
    for(int i=length-1;i>=0;i--){
        for(int j=1;j>=0;j--){
           for(int m=k;m>=0;m--){
               if(m==k&&j==0){
                   continue;
               }
               if(j==1){ //持仓
                   dp[i][j][m]=Math.max(prices[i]+dp[i+1][0][m],dp[i+1][1][m]); 
               }
              else if(j==0){//空仓
              dp[i][j][m] = Math.max(-prices[i] + dp[i+1][1][m+1],dp[i+1][0][m]);
               }
           } 
        }
    }    
 return dp[0][0][0];  
    }
}

leetcode714. 买卖股票的最佳时机含手续费

题目:交易含手续费,无数次交易
做法:操作时候把手续费算上

class Solution {
  public int maxProfit(int[] prices, int fee) {
   int[][] dp=new int[prices.length][2];
   if(prices.length<2) return 0;  
        dp[0][1]=-prices[0];
        dp[0][0]=0;  
    for(int i=1;i<prices.length;i++){
        dp[i][0]=Math.max(dp[i-1][0],dp[i-1][1]+prices[i]-fee);
        dp[i][1]=Math.max(dp[i-1][1],dp[i-1][0]-prices[i]);   
    }  
     return  dp[prices.length-1][0];  
    }  
}

你可能感兴趣的:(hard,ez,mid)