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

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;
    }
}

方法二:动态规划(一维数组)
这个动态规划和上面的贪心没啥去别
在这里插入图片描述

状态转移方程
在这里插入图片描述

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];
}
}

方法三:贪心

lass Solution {
    public int maxProfit(int[] prices) {
    int length = prices.length;
    int res =0;
    for(int i=1;i<length;i++){
      res += Math.max(prices[i]-prices[i-1],0);
    }
     return res;
    }
}

和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]);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值