思路分析
主要思路:贪心+分治。
题目要求的是两段收益最大区间的收益之和,主要使用到的一个性质是:
第
天对应时间的价格简记为
。
假设在给定的数据范围内,已经找到了当前收益最大的一次买卖操作时间,买入时间记为
、卖出时间记为
,有
。
则不存在满足
。
即:在范围 内的全局最优解一定大于任意两个局部最优解之和,因此不需要去考虑重叠子的问题,直接贪心即可。
代码
主要思路:先找到全局完整区间内的最优解(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)