LeetCode 买卖股票的最佳时间系列习题 python(上)

121.买卖股票的最佳时间 I

题目内容

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。
注意你不能在买入股票前卖出股票。

思路

引入两个变量,最小买入价格和最大利润,遍历数组,判断最大和最小值来得到最后的结果。

代码

class Solution:
    def maxProfit(self, prices):
        """ :type prices: List[int] :rtype: int """
        if len(prices)<2:
            return 0
        min_price = prices[0]
        max_profile = 0
        for i in prices:
            min_price = min(min_price, i)
            max_profile = max(max_profile, i - min_price)
        return max_profile

122.买卖股票的最佳时间 II

题目

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

思路1

与 I 中的区别是可以进行尽可能多的交易。同样,不能参与多笔交易。
可以使用贪心算法。
低价买入,向后判断,高于前一天的价格即可卖出。之后将这一天的价格买入,继续向后判断。

代码

class Solution:
    def maxProfit(self, prices):
        """ :type prices: List[int] :rtype: int """
        if len(prices)<2:
            return 0
        min_price = prices[0]
        max_profile = 0
        for i in prices:
            if i > min_price:
                max_profile = max_profile + i - min_price
            min_price = i
        return max_profile

思路2

要进行尽可能多的交易,则可以判断相邻两天的股票价格,如果为差值为正,那么就可以将差值累加,得到最后的利润。

代码

class Solution:
    def maxProfit(self, prices):
        """ :type prices: List[int] :rtype: int """
        if len(prices) < 2:
            return 0
        price = prices[0]
        profile = 0
        for i in range(1, len(prices)):
            profile = profile + max(prices[i]-prices[i-1], 0)
        return profile

123.买卖股票的最佳时间 III

题目

给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。
注意: 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

思路1

可以想到,这是121题的扩展,所以可以想到将数组分为前后两部分,前一部分的最大值加上后一部分的最大值即为整体的最大值。但是,将数组分为前后两部分的方式有许多种,还需要判断哪一种分割方式得到的才是最大值。
在做题过程中,简单的运用分割方式的话,出现超时的问题,所以进行了改进,得到可行的代码,代码如下:

代码(超时)

class Solution:
    def maxProfit(self, prices):
        """ :type prices: List[int] :rtype: int """
        if len(prices) < 2:
            return 0
        m = 1
        max_profile3 = prices
        while(True):
            min_price = prices[0]
            max_profile = 0
            for i in range(m):
                min_price = min(min_price, prices[i])
                max_profile = max(max_profile, prices[i]-min_price)
            min_price = prices[m-1]
            max_profile2 = 0
            for j in range(m-1,len(prices)):
                min_price = min(min_price,prices[j])
                max_profile2= max(prices[j]-min_price, max_profile2)
            max_profile3.append(max_profile + max_profile2)
            if m == len(prices):
                break
            m = m + 1
        return max(max_profile3)

在这段代码中,一个循环下,还有两个循环,代码复杂度过高,所以考虑精简算法。这段代码将最后的结果都写入max_profile3的数列中。所以,可以考虑,分别定义两个数组,将前半段的最大值和后半段的最大值分别写入两个数组,将整体的最大值的判断写入一个循环,三个循环串行,复杂度减小。

代码(修改)

class Solution:
    def maxProfit(self, prices):
        """ :type prices: List[int] :rtype: int """
        if len(prices) < 2:
            return 0
        profile1 = [0 for i in range(len(prices))]
        profile2 = [0 for i in range(len(prices))]
        max_profile = 0
        min_price = prices[0]
        max_price = prices[len(prices)-1]
        for i in range(len(prices)):
            min_price = min(min_price, prices[i])
            profile1[i] = max(profile1[i-1], prices[i]-min_price)

        for j in range(len(prices)-1,-1,-1):
            max_price = max(max_price, prices[j])
            profile2[j] = max(profile2[j-1], max_price-prices[j])

        for i in range(len(prices)):
            max_profile = max(max_profile, profile1[i]+profile2[i])

        return max_profile

之后还看到有大神的解法,使用动态规划的思想,只需10行左右的代码,这部分将在下一篇中进行分享。

点赞