Python每日一练-----买卖股票的最佳时机Ⅱ

(day17)

​​​​​​​

目录

🖍题目:

题目分析:

解题思路:

🌈贪婪算法

🌈动态规划解法


🖍题目:

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

在每一天,你可能会决定购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以购买它,然后在 同一天 出售。返回 你能获得的 最大 利润 。(1 <= prices.length <= 3 * 104)

 🌠示例 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 。
     (注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。因为这样属于同时参与了多笔交易,不满足最多只能持有一股股票的要求,你必须在再次购买前出售掉之前的股票。)

最大利益 = 4

🌠示例 3:

输入: prices = [7,6,4,3,1]

输出: 0

说明: 在这种情况下, 没有交易完成, 所以最大利润为 0。(这里要求利润不能为负数)

题目分析:

题目要求在只能持有一股股票的情况下,进行购进和抛售,使得获取最大利益。可以在同一天买入和抛售,因为当天买卖股票的价格不变,所以这一天买卖股票的利益 = 0

以例1prices = [6,1,3,5]为例,最大利益 =(5-1)= 4,有很多人可能会想,我怎么知道要在第二天买入股票右在第四天卖出?实际上这会把问题复杂化。且看,换另一种计算方法   最大利益=(3-1)+(5-3)= 4.那么就有,我们只需要比较后一天的股票售价和前一天的股票售价,如果后一天的股票售价较高就可以出售。这就是贪婪算法。

解题思路:

解法一(贪婪算法)

根据贪婪算法(又叫贪心算法),我们只需比较后一天的股票售价和前一天的股票售价,如果后一天的股票售价较高就可以出售,出售获得的 利润=后一天股价 - 前一天股价

解法二(动态规划化)

上动态规划五部曲

1.分析确定dp数组以及其下标的含义

创建二维列表dp = [[0, 0], [0, 0]........[0, 0]]

为什么不创建一维列表?

因为我i们要表示两个状态:dp[i][0]表示第i天不持有股票,dp[i][1]b表示持有股票

2.确定递推公式 

根据上两个状态

1.第i天持有股票(dp[i][1])

那么可能的结果有:(1)第i-1天也持有股票,(2)第i-1天买入

prices[i]为股价

那么第i天持有股票得到得利润为

dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i])

2.第i天不持有股票(dp[i][0])

那么可能的结果有:(1)第i-1天不持有股票,(2)第i-1天抛售

那么第i天持有股票得到得利润为

dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i])

那为什么第i天第状态不去判断今天买入或者抛售?

因为第i天买入抛售的结果已经包含在持不持有股票中。

最后不持有股票得状态即为本题的解(没抛售股票获得的利润一定小于抛售后)

3.如何初始化dp数组

由公式可知,dp[i][0], dp[i][1],是以dp[0][0], dp[0][1],为基础的

那么dp[0][0] = 0,(因为不持有股票)

dp[0][1] = - prices[0],(因为购入了股票)

4.确定遍历的顺序

显然,dp[i][x]的递推方式为顺推

5.举例验证推导的dp数组(公式)是否正确

可以以例1为例检验

代码实现

🌈贪婪算法

def maxProfit(prices):
    ans = 0
    for i in range(1, len(prices)):  
        if prices[i] > prices[i - 1]:
            ans += prices[i] - prices[i - 1]
    return ans

✏代码注释

def maxProfit(prices):
    ans = 0      # 初始化利润
    for i in range(1, len(prices)):   # 由于prices[i-1]的限制,i从1开始。
        if prices[i] > prices[i - 1]:  # 比较前一天股价和后一天股价
            ans += prices[i] - prices[i - 1]  # 计算获得的利润
    return ans   # 返回结果

🌈动态规划解法

def maxProfit(prices):
    dp = [[0] * 2 for _ in range(len(prices))]
    dp[0][0] = 0
    dp[0][1] = - prices[0]

    for i in range(1, len(prices)):
        dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i])
        dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i])

    return dp[len(prices) - 1][0]

✏代码注释

def maxProfit(prices):
    dp = [[0] * 2 for _ in range(len(prices))]  # 创建二维数组用于储存持有或不持由股票时的利润
    dp[0][0] = 0     # 初始化公式基础
    dp[0][1] = - prices[0]

    for i in range(1, len(prices)):  # 由于dp[i-1]的限制,i从1开始
        dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i])  # 用max()取持有或不持由股票时利润最大值
        dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i])

    return dp[len(prices) - 1][0]   # 返回最终不持由股票的状态

今天就到这,明天见。🚀

❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄end❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

亖夕

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

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

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

打赏作者

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

抵扣说明:

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

余额充值