LeetCode 122. 买卖股票的最佳时机 II
题目描述


题意分析
给定数组
prices,prices[i]是第i天的股价,返回能获得的最大总利润。交易规则是本题的核心信号:可以进行任意多次买卖,但同一时间最多持有一股,也就是必须先卖掉手里的股票才能再买;题目还明确允许「当天买入、当天卖出」。这和 121 题形成直接对照——121 全程只允许一笔交易,答案是单段最大差价;本题交易次数不限,答案是把所有能赚的段都赚到。
约束上
prices.length至少为1,价格非负。边界情况:只有一天无法完成任何交易,利润为0;价格一路下跌时最优策略是不交易,利润同样为0(利润不会为负)。
解法:贪心累加所有上涨差价
核心思路
交易次数不限时,一段上涨行情的利润可以拆成每天的正差价。例如
1 → 3 → 5的利润4,等于(3 - 1) + (5 - 3)。因此遍历相邻价格,只累加所有正差价,就能获得每段上涨且避开所有下跌。
解题步骤
- 从第二天开始,计算当天与前一天的价格差。
- 差价为正时累加到利润中;非正时跳过。
- 遍历结束后返回累计利润。
代码实现
class Solution {
public int maxProfit(int[] prices) {
int ans = 0;
for (int i = 1; i < prices.length; i++) {
if (prices[i] > prices[i - 1]) {
ans += prices[i] - prices[i - 1];
}
}
return ans;
}
}
func maxProfit(prices []int) int {
ans := 0
for i := 1; i < len(prices); i++ {
if prices[i] > prices[i-1] {
ans += prices[i] - prices[i-1]
}
}
return ans
}
复杂度分析
- 时间复杂度:$O(n)$,只遍历价格数组一次。
- 空间复杂度:$O(1)$。
关键点总结
- 多次交易允许收集每一段上涨,利润等于所有正相邻差价之和。
- 下跌和持平不会产生收益,直接跳过。
- 该贪心依赖“交易次数不限且无手续费、冷冻期”等额外限制。
易错点总结
- 套用第 121 题的单次交易逻辑,会漏掉后续上涨区间。
- 循环应从下标
1开始,否则访问前一天会越界。- 只累加正差价,不能对差价取绝对值。
- 单元素或持续下跌数组应返回
0。
相似题目
| 题目 | 难度 | 考察点 |
|---|---|---|
| 121. 买卖股票的最佳时机 | 简单 | 只许一笔交易,维护历史最低价 |
| 123. 买卖股票的最佳时机 III | 困难 | 至多两笔交易,四状态 dp |
| 188. 买卖股票的最佳时机 IV | 困难 | 至多 k 笔交易,通用状态机 |
| 309. 买卖股票的最佳时机含冷冻期 | 中等 | 卖出后隔一天才能买,状态多一维 |
| 714. 买卖股票的最佳时机含手续费 | 中等 | 每笔交易有成本,裂项贪心失效 |
| 剑指 Offer 63. 股票的最大利润 | 中等 | 121 的剑指版,单笔交易求最大差价 |