leetcode之买卖股票的最好时机

本文解析了如何使用动态规划解决LeetCode中的股票买卖问题,介绍了关键变量min_price和max_profit的应用,以及如何通过遍历和更新找到最大利润。适合初学者理解动态规划在实际问题中的应用。

题目描述

给定一个数组 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

解题思路:

我一开始用的双指针,但是发现思路行不通,后来想不出来就用了一个双层循环,但可想而知会超时,最后看了题解,感觉顿时就明白了,主要运用到了动态规划。

题解中主要运用到了两个变量

一个当前股价的最小值:这个值的更新方法为很简单,一开始假设其值为列表的第一个元素,之后在遍历列表时,如果当前值小于它,就将当前值赋给它,这样购入最低股票的日期就永远在卖出股票日的前面了

一个是利润的最大值:初始值设为0,在遍历列表的时候,如果当前值-股价最低值大于此时的利润最大值,就将此值更新为该值

源码:

from typing import List

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        min_price = prices[0]  # 假设第一天的价格最低
        max_profit = 0  # 初始时最大利润设为0
        for cur_p in prices:
            max_profit = max(max_profit, cur_p - min_price) #当前利润=当天的价格-目前最低的价格 用当前利润和最大利润进行比较
            min_price = min(min_price, cur_p) #最低价格也要更新
            # print(f'{cur_p} {min_price} {max_profit}')

        return max_profit

通过截图:

 同步更新于个人博客系统:leetcode之买卖股票的最佳时机 

 同步更新于个人博客系统:leetcode之买卖股票的最佳时机 

同步更新于个人博客系统:leetcode之买卖股票的最佳时机 

### LeetCode 122 买卖股票最佳时机 II 的解决方案和思路 #### 动态规划方法解析 对于此问题,动态规划提供了一种有效的方法来解决。通过定义两个状态变量——持有股票的状态 `hold` 和未持有股票的状态 `not_hold` ,可以在遍历价格列表的过程中不断更新这两个状态所对应的最优解。 当处于持有状态时,意味着要么之前已经持有了这支股票并继续保留它;要么是在当前日买入了新的股票。而如果处在未持有的状态下,则表示可能前一天就没有持股或者是今天刚刚把手中的股票给卖出去了[^2]。 因此,在每一天结束之际: - 如果选择保持持有,则最大收益等于昨天持有加上今天的股价变化(如果是正向增长),或者说是昨日不持有但今日购入的成本; - 若决定不再持有,那么就取两者之间的较大者作为这一天结束后最好的情况:即延续之前的无股状况不变或是卖掉现有股份所带来的额外收入。 具体实现方面,可以通过一次循环完成所有操作,并且仅需常量空间存储必要的中间结果。 ```python def maxProfit(prices): not_hold, hold = 0, float('-inf') for price in prices: not_hold, hold = max(not_hold, hold + price), max(hold, not_hold - price) return not_hold ``` 这段代码实现了上述逻辑,其中 `float('-inf')` 表示负无穷大,用来初始化不可能的情况下的最小值。最终返回的是 `not_hold` 变量中的数值,因为到最后一天为止,手中不应该还留有任何尚未售出的股票才能达到最高利润[^5]。 #### 贪心算法的应用 另一种更直观也更容易理解的方式是采用贪心策略解决问题。这里的核心思想在于每当遇到价格上涨的机会就要抓住机会赚取差价。换句话说,只要发现明天的价格高于今天就可以考虑在这两天之间进行交易以获取这部分增值部分的价值。 这种方法背后的原理其实很简单:假设存在一段连续上涨的趋势 `[a,b,c,d,e]` (其中 a<b<c<d<e),那么无论是一次性从最低点买到最高点还是分多次逐步累积这些增量都能得到相同的总收益 `(e-a)` 。而对于非单调递增的情形来说,局部的小幅波动同样适用这一原则,只需关注那些确实能够带来正面回报的变化即可[^4]。 以下是基于这种想法编写的 Python 函数版本: ```python def maxProfit_greedy(prices): profit = 0 for i in range(len(prices) - 1): diff = prices[i + 1] - prices[i] if diff > 0: profit += diff return profit ``` 以上两种方式都可以很好地处理这个问题,并且时间复杂度均为 O(n),n 是数组长度。实际应用中可以根据个人喜好或特定场景的需求选取合适的一种来进行编码实践。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值