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