leetcode第一百二十三题——买卖股票的最佳时机二

这道题是股票系列的第三题,限制你最多买卖两次,其实就是买卖两次。

1.题目

原题:

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

例子:

输入: [3,3,5,0,0,3,1,4]
输出: 6
解释: 在第 4 天(股票价格 = 0)的时候买入,在第 6 天(股票价格 = 3)的时候卖出,这笔交易所能获得利润 = 3-0 = 3 。
     随后,在第 7 天(股票价格 = 1)的时候买入,在第 8 天 (股票价格 = 4)的时候卖出,这笔交易所能获得利润 = 4-1 = 3 。

2.解析

只讲动态规划思路,暴力求解不考虑了。
(1)一次方法的引申
还记得买卖一次的动态规划思路吗,要记录一个当前的最大收益,要记录一个当前天之前的最小值。当前最大收益就是max(dp[i-1],p[i]-minv),最小值就是min(p[i],minv)。
到了这道题加入了一个买卖次数的限制,就是一维的dp转换为二维,dp[i][j],i代表第几天,j代表第几次买卖。这下问题好说了,首先这个问题就两次j就0和1两个取值,0就是第一个交易,更一次买卖思路是一样的,1是第二次交易,首先考虑收益最大值,max(dp[i-1][1],prices[i]-minv),这个minv的更新比较有意思,因为已经买卖一次了,所以你第二次买股票成本要减去第一次收益,最小值就是min(minv,p[i]-dp[i-1][0]),然后动态规划最优值就是最后一个位置的取值。返回dp[-1][-1]。
(2)其他方法
想到更好的就更新。

3.python代码

思路1的代码
#一个关键点是第二次买卖初始价格要更新哦
class Solution:
    def maxProfit(self, prices):
        if not prices or len(set(prices)) == 1:
            return 0
        m = len(prices)
        dp = [[0, 0] for _ in range(m)]
        minj = prices[0]
        for i in range(1, m):
            dp[i][0] = max(dp[i-1][0], prices[i]-minj)
            minj = min(prices[i], minj)
        minj = prices[0]
        for i in range(1, m):
            dp[i][1] = max(dp[i-1][1], prices[i]-minj)
            minj = min(prices[i]-dp[i-1][0], minj)
            print(minj)
        return dp[-1][-1]

你可能感兴趣的:(leetcode第一百二十三题——买卖股票的最佳时机二)