力扣LeetCode121.买卖股票的最佳时机及Python源码实现

本题为LeetCode题库中第53题最大子序列求和,难度简单,题目请参考这里。

一道很简单的DP(Dynamic Programming)算法的题目,代码不难但思想需要考究如何找出动态规划中的转态方程,所以在这记录一下。

给定一个数组,它的第 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。

解决思路:这种题目明显一看就是DP算法,但首先不考虑DP算法。显然,我们采用两层循环分别来定位买入和卖出的价格,当然第二层循环要从第一层循环i+1开始走,因为不能在买入股票前卖出股票,然后找出差值最大的数也就是最大利润了。代码很简单如下:(按照LeetCode上面的格式进行编写)

class Solution: #暴力解决,双循环
    def maxProfit(self, prices) -> int:
        temp = 0
        for i in range(len(prices)):
            for j in range(len(prices)-1,i,-1):
                temp = max(temp,prices[j] - prices[i])
        return temp

如果这么交上去,LeetCode报错,超出时间限制。分析一下原因:两层循环,时间复杂度为O(n^2)。没办法只能试试DP算法(毕竟菜),这道题的难点就在于如何找到状态转移方程,一步一步来。

这道题求的是最大利润,怎么计算的呢?用第i天的价格减去前面i-1天中最小的价格不就是最大利润了嘛。那怎么实现状态转移?那我们想一想i-1天的最大利润,如果第i-1天的最大利润比i天计算出的最大利润大,那么最大利润就是i-1天的利润,否则最大利润就是第i天求出的最大利润。

状态转移方程:前i天最大利润=max(前i-1天最大利润,第i天的价格-前i-1天中的最小价格)。状态转移方程出来了代码就出来了,代码就出来了???(黑人脸问号)反正我是出不来!毕竟刚上手算法(LeetCode),想一想需要一个变量来存储最大利润,然后需要一个循环来遍历整个数组用来寻找第i天的最大利润。

Python源码实现:按照LeetCode上面的格式进行编写(其中有很多技巧和BUG请看代码和注解)

class Solution:
    def maxProfit(self, prices) -> int:
        if len(prices) == 0: #先做个判断如果为空则直接返回0不然下面会报错list out of range
            return 0
        mem = 0
        min_ = prices[0]
        for i in range(1,len(prices)): 
            min_ = min(min_,prices[i-1]) #记录i-1天中的最小值
            temp = max(mem,prices[i]-min_) #如果在这直接用min(prices[:i])会报错因为leetcode测试会用长数组导致超时
            mem = temp
        return mem

 

你可能感兴趣的:(LeetCode)