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 。

思路分析

今天这个是昨天那个股票问题的升级版: 121. 买卖股票的最佳时机
昨天那个题是只能买卖一次,今天这个是可以无限买卖。

直接贪心会很简单,不过还是为了考试为了面试,得学一下动态规划的方法。

和昨天那道题一样的东西我就不说了,没做过的先做上一题。

贪心思路:

本着有便宜不占王八蛋的原则,只要今天买入,明天卖掉能挣钱就卖。(手里最多只能持有一支股票)

所以,遍历数组,如果后一天比前一天数值大,则记录差值。最后所有的差值和就是要求的最大利润。

动规思路:

这道题和上一道题只有状态转移公式不一样。

先回顾一下上一道题的dp含义:

dp[i][0] 表示第 i 天持有股票时手里的最大现金。

dp[i][1] 表示第 i 天不持有股票时手里的最大现金。

注意:无论何时,手里最多只能手持一股股票。也就是说 你不能连续的买入。

如果第 i 天持有股票,则:

  • 是第 i 天买入的,则此时dp[i][0] = dp[i-1][1]-prices[i]。上一题是-prices[i]。因为上一道题是规定了只能买一次,所以肯定是-prices[i],而这道题可以多次买入,所以是上一个没有股票的状态下手里的现金减去当前要买入的股票价格。
  • 不是第 i 天买入的,是之前几天买入的,则dp[i][0] = dp[i-1][0]。

如果第 i 天不持有股票,则:

  • 是第 i 天卖出的,则此时 dp[i][1] = dp[i-1][0] + prices[i] 、
  • 不是第 i 天卖出的,是前几天就卖掉了的,则dp[i][1] = dp[i-1][1]

所以
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])

完整代码


贪心思路:
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        res = 0
        for i in range(len(prices)-1):
            if prices[i] < prices[i+1]:
                res +=  prices[i+1] - prices[i]


        print(res)
        return res

动态规划思路:
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        dp = [[0 for i in range(2)] for j in range(len(prices))]
        # dp[i][0] 表示第i持有,手里最大的现金。
        # dp[i][1] 表示第i天不持有股票,手里最大的现金。
        dp[0][0] = -prices[0]
        dp[0][1] = 0
        for i in range(1,len(prices)):
            # 两个状态  1.i天之前就已经买入,不是今天买入的,保持现状
            # 2. 今天买入的,因为题目说了手里只能持有一只股票,所以是前一天不持有股票时的状态来买入,
            # 也就是前一天不持有股票状态下的手里现金减去今天要买的股票的价格
            dp[i][0] = max(dp[i-1][0],dp[i-1][1]-prices[i])
            # 同样是两个状态,1.手里不持有股票,前几天就已经卖掉了,则保持现状
            # 2. 今天卖掉的,则是前一天持有股票的状态+今天要卖掉的股票价格
            dp[i][1] = max(dp[i-1][1],dp[i-1][0]+prices[i])
        return dp[-1][1]
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
根据引用\[1\]和引用\[2\]的内容,买卖股票最佳时机可以使用动态规划算法来解决。动态规划是一种通过将问题分解为子问题并利用子问题的解来求解原问题的方法。在这个问题中,我们可以定义一个状态数组dp,其中dp\[i\]表示第i天卖出股票所能获得的最大利润。然后,我们可以通过遍历价格数组prices,计算出每一天卖出股票所能获得的最大利润,并更新dp数组。最后,dp数组中的最后一个元素即为所求的最大利润。 根据引用\[3\]的内容,区间动态规划算法是解决买卖股票最佳时机问题的一种方法。在这个算法中,我们需要考虑每个可能的买入和卖出的时间点,并计算出每个时间点的最大利润。然后,我们可以通过比较这些最大利润,找到最大的利润作为结果。 所以,买卖股票最佳时机可以使用区间动态规划算法来解决。 #### 引用[.reference_title] - *1* *3* [【算法-LeetCode】121. 买卖股票最佳时机动态规划贪心)](https://blog.csdn.net/qq_44879358/article/details/120306943)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [【算法-LeetCode122. 买卖股票最佳时机 II动态规划贪心)](https://blog.csdn.net/qq_44879358/article/details/120783546)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

深度不学习!!

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

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

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

打赏作者

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

抵扣说明:

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

余额充值