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

题目链接:

力扣

题目描述:

给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。

你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。

返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。

示例 1:

输入:[7,1,5,3,6,4]
输出:5
解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
     注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。
示例 2:

输入:prices = [7,6,4,3,1]
输出:0
解释:在这种情况下, 没有交易完成, 所以最大利润为 0。
 

提示:

1 <= prices.length <= 105
0 <= prices[i] <= 104

首先介绍贪心算法的解法吧

解题思路:

贪心算法的特点是从局部最优推全局最优

这里的局部最优是遍历到第i天则计算第i天的股票价格对利润的影响,以此确定前i天这个局部的最大利润。一直遍历完数组,则这个最大利润就是所求整体的最大利润,具体算法如下

分成2个区间,已知区间(前i天)和未知区间(i天之后),存储区间最小值,则遍历到第i天时最大利润profit = max(profit, prices[i] - min_prices)。profit初始化为0,区间最小值初始化为prices[0]

代码如下:

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        min_price = prices[0]
        profit = 0
        for price in prices[1:]:
            if price < min_price: min_price = price#如果第i天的股票价格比当前存的最低价格还小,那么它造成的利润(是个负数)必然小于当前所存的利润,这时直接拿它更新最小值就好了
            elif price - min_price > profit: profit = price - min_price#更新最大利润
        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(前一天持有股票地最大利润,前一天没持有股票地最大利润-今天股票的价格即今天把股票买了,这里是因为只能买一次,所以不持有股票地利润只能是0,所以写成 -prices[i])

初始化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
        for i in range(1, len(prices)):
            dp10 = max(dp00, dp01 + prices[i])
            dp11 = max(dp01, -prices[i])#这里是因为只能买一次,所以不持有股票地利润只能是0,如果写成dp00 - prices[i]就是可以买卖对此股票了
            dp00 = dp10
            dp01 = dp11
        return dp10#最后返回的是到最后一天不持有股票的最大利润(因为不持有股票的最大利润必然大于持有的最大利润,都把股票卖了肯定更有钱)

最后的运行结果是贪心算法的速度更快:下图分别是贪心和动态规划的运行情况

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

翔空中,策人生

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

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

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

打赏作者

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

抵扣说明:

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

余额充值