Leetcode每日一题——122. 买卖股票的最佳时机 II。动态规划+贪心算法

题目链接:

力扣

题目描述:

给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。

在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。

返回 你能获得的 最大 利润 。

示例 1:

输入:prices = [7,1,5,3,6,4]
输出:7
解释:在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4 。
     随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6 - 3 = 3 。
     总利润为 4 + 3 = 7 。
示例 2:

输入:prices = [1,2,3,4,5]
输出:4
解释:在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4 。
     总利润为 4 。
示例 3:

输入:prices = [7,6,4,3,1]
输出:0
解释:在这种情况下, 交易无法获得正利润,所以不参与交易可以获得最大利润,最大利润为 0 。
 

提示:

1 <= prices.length <= 3 * 104
0 <= prices[i] <= 104

先说说贪心的解法吧:

贪心算法的思路是通过局部最优推得全局最优。这里把一买一卖看成一个交易,相邻2天就可以完成一个交易,只要交易有获利(局部获利)我们就进行,否则不进行。最终所有的局部获利之和就是所求全局最大获利,因为我们充分地利用了每次交易去获利了。具体代码如下:

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        profit = 0#统计局部获利之和
        for i in range(1, len(prices)):
            if prices[i] > prices[i - 1]: profit += prices[i] - prices[i - 1]#如果后一天的股票价格比前一天高,那么我们就可以通过这次交易获利(前一天买进,后一天卖出)。累加局部获利
        return profit#局部获利累加结果即为全局最大获利

下面再说说动态规划的算法:

dp四部曲:

        确定dp数组:dp[i][0]表示第i天不持有股票地最大利润,dp[i][1]表示第i天不持有股票地最大利润.

        确定递推公式:dp[i][0]=max(dp[i-1][0], dp[i-1][1]+prices[i])表示第i天不持有股票地最大利润为max(前一天不持有股票地最大利润,前一天持有股票地最大利润+今天股票地价格即今天把股票卖了)。。。dp[i][1]=max(dp[i-1][1], dp[i-1][0]-prices[i])表示第i天持有股票地最大利润为max(前一天持有股票地最大利润,前一天没持有股票地最大利润-今天股票的价格即今天把股票买了)

        初始化dp数组:dp[0][0]=0,dp[0][1]=-prices[0],其他都初始化为0

        遍历顺序:顺序遍历,因为存在着前后依赖关系。因为dp[i]的情况只与dp[i-1]有关,所以考虑滚动数组,用dp00, dp01, dp10, dp11分别代替dp[i-1][0],dp[i-1][1],dp[i][0],dp[i][1]

代码如下:

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        dp00, dp01, dp10, dp11 = 0, -prices[0], 0, 0#初始化dp值
        for i in range(1, len(prices)):
            dp10 = max(dp00, dp01 + prices[i])#第i天不持有股票的最大利润
            dp11 = max(dp01, dp00 - prices[i])#第i天持有股票的最大利润
            dp00 = dp10
            dp01 = dp11
        return dp10#返回最后一天不持有股票的最大利润,因为不持有股票的最大利润肯定是大于持有股票的最大利润的,把股票卖了钱肯定更多啊

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

翔空中,策人生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值