思路分析
主要思路:贪心+分治。
题目要求的是两段收益最大区间的收益之和,主要使用到的一个性质是:
第
天对应时间的价格简记为
。
假设在给定的数据范围内,已经找到了当前收益最大的一次买卖操作时间,买入时间记为
、卖出时间记为
,有
。
则不存在满足
。
即:在范围  内的全局最优解一定大于任意两个局部最优解之和,因此不需要去考虑重叠子的问题,直接贪心即可。
代码
主要思路:先找到全局完整区间内的最优解(26行),再在最优解所划分的左右两半区间中找到次优解(27、28行),求和(29行)。对给定区间进行求解的算法可以参考 BM80 买卖股票的最好时机(一) 解法(6-24行)的最优实现( 空间、
 时间)。
总复杂度:在三次执行find中最多完整地遍历两次 prices,  空间、
 时间。
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        # write code here
        n = len(prices)
        def find(left, right):
            i_ma = i_mi = left
            r_ma = r_mi = left
            profit = 0
            for i in range(left, right):
                ma = prices[i_ma]
                mi = prices[i_mi]
                p = prices[i]
                if p >= ma:
                    i_ma = i
                    # profit = max(profit, prices[i_ma] - prices[i_mi])
                elif p < mi:
                    i_mi = i_ma = i
                if profit < prices[i_ma] - prices[i_mi]:
                    profit = prices[i_ma] - prices[i_mi]
                    r_ma, r_mi = i_ma, i_mi
                profit = max(profit, prices[i_ma] - prices[i_mi])
            print(f"find({left}, {right})", profit, r_mi, r_ma)
            return profit, r_mi, r_ma
        ans, i, j = find(0, n)
        v1, _, _ = find(0, i)
        v2, _, _ = find(j, n)
        return ans + max(v1, v2)

京公网安备 11010502036488号