leetcode:买卖股票的最佳时机(python)

1. 题目描述

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。

如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。

注意你不能在买入股票前卖出股票。

示例 1:

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

示例 2:

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

2. 1 常规思路

我们可以设置两个变量,一个变量表示当前的最小价格,一个变量表示当前的最大利润。遍历这个数组,先更新目前为止的最小价格,然后再将当前的价格减去当前的最小价格(利润),以此为根据更新最大利润。遍历完数组,返回最大利润即可。

2.1 Python代码

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        minPrice = float("inf")
        maxProfit = 0
        if len(prices) == 0:
            return 0
        for num in prices:
            if num < minPrice:
                minPrice = num
            if num - minPrice > maxProfit:
                maxProfit = num - minPrice
        return maxProfit
            

2.2 动态规划

这类股票问题牵扯到可进行股票买卖的次数,因为股票买卖次数的限制,不能随便的进行买入卖出,但是这个问题限制了股票买卖的次数k为1,因此在进行状态转移方程的推导过程中,当k等于0时,dp[i][0] = 0,即不进行股票买卖也不持有股票的利润为0。在推导过程中其他的涉及到k的地方,都是k=1,所以k对状态之间的转移没有影响。
leetcode:买卖股票的最佳时机(python)_第1张图片
leetcode:买卖股票的最佳时机(python)_第2张图片

2.2 动态规划代码

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        if len(prices) == 0:
            return 0
        n = len(prices)
        dp = [[0 for i in range(2)] for i in range(n)]
        dp[0][0] = 0
        dp[0][1] = -prices[0]
        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]      

和其他的动态规划一样,状态之间转换仅仅依靠相邻的两个状态,因此不用开辟一个二维数组,只需要记录两个相邻的状态即可,是空间复杂度降为o(1)。

动态优化优化代码

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        if len(prices) == 0:
            return 0
        n = len(prices)
        dp_0_0 = 0   # 不持有
        dp_0_1 = -prices[0]   # 持有
        for i in range(1,n):
            dp_0_0 = max(dp_0_0,dp_0_1 + prices[i])
            dp_0_1 = max(dp_0_1,-prices[i])
        return dp_0_0

你可能感兴趣的:(leetcode)