#122
简单
低频
贪心买卖股票的最佳时机 II
这是一道围绕数组展开的高频练习。建议先掌握「贪心」这套写法,再结合下方步骤讲解理解状态维护、边界处理和复杂度取舍。
数组
题目分析
这道题表面上是在处理「买卖股票的最佳时机 II」,但先要想清楚题目到底让你返回什么,以及过程中哪些约束必须一直满足。从题型上看,它主要在考 数组 这些能力。先别急着写代码,先把题目要求翻译成人话,明确结果是什么、约束是什么、过程里要持续维护什么。只有先把题目要求翻译成人话,后面的推荐代码才是在实现思路,而不是直接给答案。
接下来怎么看推荐代码: 带着这个理解再看推荐代码时,重点观察这条主线:只要今天价格高于昨天,就把这段上涨差价计入利润,等价于在所有上升段低买高卖。
推荐代码
推荐解法:贪心
时间复杂度: O(n)
空间复杂度: O(1)
核心思路: 只要今天价格高于昨天,就把这段上涨差价计入利润,等价于在所有上升段低买高卖。
class Solution {
public int maxProfit(int[] prices) {
int profit = 0;
for (int i = 1; i < prices.length; i++) {
profit += Math.max(0, prices[i] - prices[i - 1]);
}
return profit;
}
}结构化讲解
面试时怎么讲
开场思路
这题我会用贪心,把所有上涨差价直接加起来。
核心过程
- 从第二天开始遍历价格数组。
- 如果今天比昨天贵,就把这部分差价算进利润。
- 如果今天更便宜,就什么都不做,等下一段上涨。
- 最后累计值就是最大利润。
复杂度总结
时间复杂度 O(n),空间复杂度 O(1)。
面试补一句:要把“拆分上涨段不影响总利润”讲清楚,这就是贪心正确性的核心。
核心思路
这题允许无限次交易且不能同时持有多股,所以每一段上涨都可以独立贡献利润。把所有正向差价累加起来,就是全局最优解。
步骤讲解
1
从第二天开始遍历
比较当天价格和前一天价格的差值。
为什么这样做:利润只来自相邻两天之间的上涨部分。
对应代码提示:for (int i = 1; i < prices.length; i++) { ... }
2
只累计正差价
如果今天比昨天贵,就把差值加入答案;否则跳过。
为什么这样做:下降段不交易,上升段拆开累加与整段交易利润相同。
对应代码提示:profit += Math.max(0, prices[i] - prices[i - 1]);
易错点
误以为必须显式找买卖点
其实把每段上涨拆成相邻差价求和,结果完全等价。
正确理解:强调利润可加性:
(b-a) + (c-b) = c-a。把这题和只能交易一次混淆
那会错误地维护单次最低价而漏掉中间利润。
正确理解:先明确题目允许多次交易,策略才会变成累加所有上涨段。
复杂度与适用判断
时间复杂度:O(n)
空间复杂度:O(1)
比其他方案更好在哪里:比显式维护买入卖出区间更简洁,且本质等价。
适用判断:当局部最优操作可以自然累积成全局最优时,优先考虑贪心。
额外提醒
- 所有正向相邻差价之和,就是允许多次交易时的最优利润。