题目描述
思路解析动画文字版
最直接的念头是「找一个谷底买进、找一个峰顶卖出」。但能交易很多次,到底切成几段、每段谷峰在哪,枚举起来又乱又慢,而且根本没必要知道具体的买卖点。
换个角度:把利润拆到每一天。今天比昨天涨,就把这点差价收进口袋(相当于昨天买、今天卖);今天比昨天跌,就空仓什么都不做(加 0)。为什么成立:一段连续上涨 1→5 的总收益 4,正好等于它每天小涨之和;所以「把所有正的日差累加」和「整段买卖」收益完全相等,而且不限次数让我们可以自由分段——逐日贪心就是全局最优。
准备 · 从第 2 天开始:利润 profit 从 0 起。第 1 天(价 7)没有前一天可比,cur 先停在这里,真正的累加从第 2 天开始。
第 2 天 · 7 → 1 算差:走到第 2 天(价 1),先算今天减昨天:1 − 7 = −6,是负的。
第 2 天 · 跌 → 加 0:日差是负的,这天不操作(空仓),profit 加 0、保持 0。这就是负例:下跌日一律跳过,灰掉表示没吃进。
第 3 天 · 1 → 5 算差:走到第 3 天(价 5),算差:5 − 1 = +4,第一次出现正的涨幅。
第 3 天 · 涨 → 吃下:日差为正,把这 4 块吃进口袋:profit 累计到 4。绿色标出的 1 和 5 就是这一段「昨天买、今天卖」赚到的钱。
第 4 天 · 5 → 3 算差:走到第 4 天(价 3),算差:3 − 5 = −2,又是负的。
第 4 天 · 跌 → 加 0:下跌日再次跳过,profit 不动,仍是 4。注意这里没有去「找谷底找峰顶」——只看相邻两天的正负就够了。
第 5 天 · 3 → 6 算差:走到第 5 天(价 6),算差:6 − 3 = +3,又一段上涨。
第 5 天 · 涨 → 吃下:正差再吃下 3 块:profit 从 4 累到 7。绿色的 3 和 6 是这第二段赚到的钱。
第 6 天 · 6 → 4 收尾:最后一天 6 → 4 又是跌,跳过。全程只把两段正涨幅累加:4 + 3 = 7,就是答案。
一段连续上涨(如 1→5)拆成每天的差,求和不变;下跌日加 0 不亏。所以「每个正的日差都拿」就等于全局最优——这就是贪心在这题成立的根本原因。
参考代码
class Solution: def maxProfit(self, prices): ans = 0 for i in range(1, len(prices)): if prices[i] > prices[i - 1]: ans += prices[i] - prices[i - 1] return ans复杂度
- 时间复杂度:O(n),只从第 2 天到最后扫一遍,每天做一次比较
- 空间复杂度:O(1),只用 profit 一个变量,不开任何数组
可套用的代码模板
记住骨架:相邻两步算增量、只累加正的。前提是「次数不限、各段收益互不影响」——否则(如只能交易一次)不能这么贪。
Python
# 「操作次数不限、收益可分段独立」的贪心都套total = 0for i in range(1, n): gain = 收益(i - 1, i) if gain > 0: total += gain # 只累加正收益return total易错点
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
加油站
LeetCode 134 · 中等 · 沿着 贪心套路 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题