121. 买卖股票的最佳时机Ⅰ

发布时间 2023-11-19 21:23:08作者: Frommoon

题目

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

法一、贪心

  • 通过维护一个变量 minprice 来记录迄今为止的最低买入价格。然后,遍历股价列表,如果当前价格小于最低买入价格,将更新最低买入价格。如果当前价格大于等于最低买入价格,计算当前价格减去最低买入价格的利润,并将其与当前的最大利润进行比较,选择较大值作为最终的最大利润。
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        minprice = float('inf')
        maxprofit = 0
        for price in prices:
            minprice = min(minprice, price)
            maxprofit = max(maxprofit, price - minprice)
        return maxprofit

法二、动态规划

  • 状态有两个:第几天,手上是否持有股票;选择是:买或者卖
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        n = len(prices)
        # 初始化动态规划数组
        dp = [[0] * 2 for _ in range(n)]

        # base case
        dp[0][0] = 0  # 第一天不持有股票,利润为0
        dp[0][1] = -prices[0]  # 第一天持有股票,利润为-buy

        # 状态转移
        for i in range(1, n):#前面处理了第一天的情况,直接从第二天开始,可以避免下标越界的发生
            dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i])  # 不持有股票的情况,取前一天也不持有股票和前一天持有股票但今天卖出的最大利润
            dp[i][1] = max(dp[i-1][1], -prices[i])  # 持有股票的情况,取前一天也持有股票和前一天不持有股票但今天买入的最大利润

        return dp[n-1][0]  # 最后一天不持有股票的利润即为最大利润