美文网首页算法学习打卡计划
leetcode第一百八十八题——买卖股票的最佳时机四

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

作者: 不分享的知识毫无意义 | 来源:发表于2020-02-20 09:15 被阅读0次

    这道题其实就是122题的一个标准化形式,是leetcode的一个惯例由简入难。

    1.题目

    原题:

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

    例子:

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

    2.解析

    这道题和只交易两次、甚至只交易一次是一样的只不过思路更复杂一些。
    1)判断数组是不是空,或者数据是不是都是一样的,如果这样直接返回0。
    2)判断交易次数,因为不能同时买卖所以理论的最大交易次数是m//2,如果k大于这个数其实就是122不限制购买了。
    3)现在考虑k满足不能同时买卖要求的情况。
    动态规划思路,需要dp数组,minp最小价格。dp这个是二维的,生成方法是交易次数和交易天数之间形成的二维数组,方法见代码。更新方法,今天的最佳收益就是昨天的最佳收益,和当前价格减最小价格的差值,注意这个只跟第k次交易的前一天数据有关。那么minp怎么更新,其实还是老思路,之前最小值和当前价格减去上次交易收益的较少者。
    (2)其他方法
    想到更好的就更新。

    3.python代码

    class Solution:
        def maxProfit(self, prices, k):
            if not prices or len(set(prices)) == 1:
                return 0
            m = len(prices)
            if k > m//2:
                res = 0
                minj = prices[0]
                for i in range(1, m):
                    if prices[i] > minj:
                        res += prices[i] - minj
                        minj = prices[i]
                    else:
                        minj = min(minj, prices[i])
                return res
            else:
                dp = [[0]*(k+1) for _ in range(m)]
                for j in range(1, k+1):
                    minp = prices[0] - dp[j-1][0]
                    for i in range(1, m):
                        dp[i][j] = max(dp[i-1][j], prices[i]-minp)
                        minp = min(prices[i]-dp[i-1][j-1], minp)
                return dp[-1][-1]
    

    相关文章

      网友评论

        本文标题:leetcode第一百八十八题——买卖股票的最佳时机四

        本文链接:https://www.haomeiwen.com/subject/htptqhtx.html