Day 43算法记录|动态规划 10(股票)

股票买卖

  • 121. 买卖股票的最佳时机
  • 122.买卖股票的最佳时机II

121. 买卖股票的最佳时机

方法一:贪心

class Solution {
    public int maxProfit(int[] prices) {
    int res = 0;
    int premin = prices[0]; //股票最低的价格

    for(int i=1;i<prices.length;i++){ //从第二天开始考虑卖股票了
      res = Math.max(res,prices[i]-premin); 
      premin = Math.min(premin,prices[i]);  //记录最底价
    }
  
   return res;
    }
}

方法二:动态规划(一维数组)
这个动态规划和上面的贪心没啥去别
Day 43算法记录|动态规划 10(股票)_第1张图片

状态转移方程
Day 43算法记录|动态规划 10(股票)_第2张图片

class Solution {
    public int maxProfit(int[] prices) {
   int len = prices.length;
   int[] dp = new int[len]; // dp[i]表示前i天的最大利润
   //初始化
   int minPrice = prices[0];
   for(int i=1;i<len;i++){
     dp[i] = Math.max(dp[i-1],prices[i]-minPrice);
     minPrice = Math.min(minPrice,prices[i]);
   }

  
   return dp[len-1];
    }
}

改进:dp[0]表示持有,dp[1]表示当天卖出的最大利润

class Solution {
    public int maxProfit(int[] prices) {
    if (prices == null || prices.length == 0) return 0;
        int length = prices.length;
        int[] dp = new int[2];
        dp[0] = -prices[0];
        dp[1] =0;
        for(int i=1;i<=length;i++){
          dp[0] = Math.max(dp[0],-prices[i-1]);//持有 1.(保持原样,不买也不卖) 2.或者卖出前一天的,再买入当天的
          dp[1] = Math.max(dp[1], dp[0] + prices[i-1]);// 不持有 1.保持原样 2.卖出当天的
        }
        return dp[1];
    }
}

122.买卖股票的最佳时机II

方法一:动态规划-二维数组
本题和121的唯一区别是本题股票可以买卖多次了(注意只有一只股票,所以再次购买前要出售掉之前的股票)hold[ ] 和 sold [ ] 可以用dp[ ][0] 和dp[ ][1]表示

class Solution {
    public int maxProfit(int[] prices) {
      int length = prices.length;
      int[] hold = new int[ length+1 ]; //hold[i]表示第i天持有股票最大的收益
      int[] sold = new int[ length+1];//是old[i]表示第i天卖出股票最大的收益
      hold[0] =  Integer.MIN_VALUE; //初始化:sold[0]=0,因为最开始不持有
      for(int i=1;i<=length;i++){
        int p = prices[i-1];
       hold[i] = Math.max(hold[i-1],sold[i-1]-p); //卖出去再买一张新的 or 一直持有之前的
       sold[i] = Math.max(sold[i-1],hold[i-1]+p); //今天卖出之前的股票 or 一直不买入
      }
 return sold[length];
}
}

方法二:动态规划 – 一维数组
当天的卖与不买的收益只与前一天有关

class Solution {
    public int maxProfit(int[] prices) {
      int length = prices.length;
      //0表示持有,1表示不持有
      int[] dp = new int[2];
      dp[0] = -prices[0];
      dp[1] =0;

      for(int i=1;i<=length;i++){
          dp[0] = Math.max(dp[0],dp[1]-prices[i-1]);
          dp[1] = Math.max(dp[1],dp[0]+prices[i-1]);
      }

 return   dp[1];
}
}

和121相比,这道题是可以多次购买,代码区别
122:既然不限制交易次数,那么再次买股票时,要加上之前的收益

//121. 只能买一次
 dp[0] = Math.max(dp[0],-prices[i-1]);//持有 1.(保持原样,不买也不卖) 2.买入当天的
 dp[1] = Math.max(dp[1], dp[0] + prices[i-1]);// 不持有 1.保持原样 2.卖出当天的


// 122.可以反复购买
//既然不限制交易次数,那么再次买股票时,要加上之前的收益
dp[0] = Math.max(dp[0],dp[1]-prices[i-1]);
dp[1] = Math.max(dp[1],dp[0]+prices[i-1]);

你可能感兴趣的:(算法,动态规划,代理模式)