当前位置: 首页 > news >正文

LeetCode 122. 买卖股票的最佳时机 II - 推荐贪心

题目描述

给定一个整数数组prices,其中prices[i]表示某支股票第i天的价格。在每一天,你可以决定是否购买和/或出售股票。你在任何时候最多只能持有一股股票。然而,你可以在同一天多次买卖该股票,但要确保你持有的股票不超过一股。

返回你能获得的最大利润

示例 1:

text

输入:prices = [7,1,5,3,6,4] 输出:7 解释:在第 2 天买入,第 3 天卖出,利润 5-1=4 在第 4 天买入,第 5 天卖出,利润 6-3=3 总利润 4+3=7

示例 2:

text

输入:prices = [1,2,3,4,5] 输出:4 解释:在第 1 天买入,第 5 天卖出,利润 5-1=4 注意你不能在第 1 天和第 2 天连续买入股票

示例 3:

text

输入:prices = [7,6,4,3,1] 输出:0 解释:没有交易完成,最大利润为 0

解法一:贪心算法(面试推荐⭐)

核心思想

只要今天的价格比昨天高,就昨天买入今天卖出。虽然这看起来像是频繁交易,但数学上等价于在价格上升波段的最低点买入、最高点卖出。

算法步骤

  1. 从第二天开始遍历价格数组

  2. 计算当天与前一天的价格差

  3. 如果价格差为正(当天价格 > 前一天价格),则累加到总利润中

  4. 返回总利润

代码实现

java

class Solution { public int maxProfit(int[] prices) { int profit = 0; for (int i = 1; i < prices.length; i++) { int diff = prices[i] - prices[i - 1]; if (diff > 0) { profit += diff; } } return profit; } }

复杂度分析

  • 时间复杂度:O(n),只需遍历一次数组

  • 空间复杂度:O(1),只使用了常数级别的额外空间

为什么这是正确的?

考虑价格序列 [1, 3, 5]:

  • 贪心算法:第1天买入,第2天卖出(利润2),第2天买入,第3天卖出(利润2),总利润4

  • 最优策略:第1天买入,第3天卖出,总利润4
    两种策略结果相同,因为 (5-1) = (3-1) + (5-3)

解法二:动态规划(通用解法)

核心思想

定义两个状态:

  • dp[i][0]:第i天结束时,不持有股票的最大利润

  • dp[i][1]:第i天结束时,持有股票的最大利润

状态转移方程

text

dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i]) // 保持空仓或卖出 dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i]) // 保持持有或买入

代码实现

java

class Solution { public int maxProfit(int[] prices) { int n = prices.length; int[][] dp = new int[n][2]; dp[0][0] = 0; // 第一天不持有股票 dp[0][1] = -prices[0]; // 第一天持有股票(需要买入) for (int i = 1; i < n; i++) { dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1] + prices[i]); dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0] - prices[i]); } return dp[n-1][0]; // 最后一天不持有股票时利润最大 } }

空间优化版本

java

class Solution { public int maxProfit(int[] prices) { int hold = -prices[0]; // 持有股票的最大利润 int notHold = 0; // 不持有股票的最大利润 for (int i = 1; i < prices.length; i++) { int prevHold = hold; hold = Math.max(hold, notHold - prices[i]); notHold = Math.max(notHold, prevHold + prices[i]); } return notHold; } }

复杂度分析

  • 时间复杂度:O(n)

  • 空间复杂度:未优化版本 O(n),优化版本 O(1)

解法三:峰谷法(直观理解)

核心思想

寻找价格序列中的连续上升波段,在每个波段的谷底买入、峰顶卖出。

算法步骤

  1. 初始化利润为0,指针i从0开始

  2. 寻找价格低谷(价格开始上升的点)

  3. 寻找价格高峰(价格开始下降的点)

  4. 计算峰谷差值并累加到利润

  5. 重复直到遍历完整个数组

代码实现

java

class Solution { public int maxProfit(int[] prices) { int profit = 0; int i = 0; int n = prices.length; while (i < n - 1) { // 寻找低谷(价格停止下降的点) while (i < n - 1 && prices[i] >= prices[i + 1]) { i++; } int valley = prices[i]; // 寻找高峰(价格停止上升的点) while (i < n - 1 && prices[i] <= prices[i + 1]) { i++; } int peak = prices[i]; profit += peak - valley; } return profit; } }

复杂度分析

  • 时间复杂度:O(n),每个元素最多被访问两次

  • 空间复杂度:O(1)

面试推荐写法

首推:贪心算法 ✅

原因:

  1. 代码最简洁(仅5-7行)

  2. 时间空间复杂度最优

  3. 容易理解和解释

  4. 面试中快速写出并分析正确性

面试回答模板:

"这道题可以使用贪心算法解决。核心思想是:只要第二天的价格比第一天高,就把这个差价算作利润。虽然看起来像是频繁交易,但实际上等价于在价格上升波段中一直持有股票。算法的时间复杂度是O(n),空间复杂度是O(1)。"

备选:动态规划

如果面试官要求更通用的解法,或者后续问题扩展(如含交易费、冷冻期等),可以使用动态规划解法。

扩展思考

如果加上交易手续费?

每次卖出时扣除手续费:

java

public int maxProfit(int[] prices, int fee) { int hold = -prices[0]; int notHold = 0; for (int i = 1; i < prices.length; i++) { hold = Math.max(hold, notHold - prices[i]); notHold = Math.max(notHold, hold + prices[i] - fee); } return notHold; }

如果加上冷冻期?

卖出后需要等待一天才能买入:

java

public int maxProfit(int[] prices) { if (prices.length <= 1) return 0; int hold = -prices[0]; int notHold = 0; int coolDown = 0; // 冷冻期 for (int i = 1; i < prices.length; i++) { int prevHold = hold; hold = Math.max(hold, coolDown - prices[i]); coolDown = notHold; notHold = Math.max(notHold, prevHold + prices[i]); } return notHold; }

总结

解法时间复杂度空间复杂度推荐指数适用场景
贪心算法O(n)O(1)⭐⭐⭐⭐⭐面试首选,代码简洁高效
动态规划O(n)O(1)~O(n)⭐⭐⭐⭐通用性强,可扩展
峰谷法O(n)O(1)⭐⭐⭐直观理解价格波段

关键点:

  • 贪心算法是本题的最优解法

  • 动态规划是解决股票问题的通用框架

  • 理解贪心算法的正确性:多次买卖的总利润等于所有上升波段差值的和

在面试中,建议先给出贪心解法,然后如果时间允许或面试官要求,再讨论动态规划解法以展示你的全面性。

http://www.jsqmd.com/news/119774/

相关文章:

  • 深入解析Linux的`pthread_create`函数:从原理到实践
  • Verl的AgentLoop流程(未完)
  • 【开题答辩全过程】以 基于Vue的茶道知识科普网站的设计与实现为例,包含答辩的问题和答案
  • cesium126,240308,Ce for Ue 加载ArcGIS WMTS Map:
  • AI 写论文哪个软件最好?虎贲等考 AI:让毕业论文创作告别 “卡壳” 与 “查重焦虑”
  • AI 写论文哪个软件最好?虎贲等考 AI:从框架到定稿的全流程学术赋能
  • 学术创作革新!虎贲等考 AI 期刊论文功能:让专业写作告别低效与焦虑
  • 第一章:从连续世界到可计算存在
  • 【转】赵玉平:人要学会找到自己的位置,才能坐稳人生的舞台!
  • 打破 AI 创作枷锁!虎贲等考 AI 双效赋能,让学术原创不设限
  • 移动平均-loss函数平滑化
  • 51N 皇后
  • 毕业季必看:9款免费AI论文神器实测,30分钟生成万字文献综述+真实文献全文引用!
  • 软件工程期末复习指南
  • AI 赋能学术演示!虎贲等考 AI PPT,让科研汇报告别 “无效努力”
  • ARC115F Migration
  • 问卷设计还在 “拍脑袋”?虎贲等考 AI:让科研调研从 “盲目发问” 到 “精准赋能”
  • 数据不 “躺平”!虎贲等考 AI 数据分析,让学术研究告别 “数字焦虑”
  • Windows系统文件dmenrollengine.dll损坏或丢失 下载修复
  • 实用指南:2025深度学习框架对决:TensorFlow与PyPyTorch深度测评
  • 实用指南:今日策略:年化398%,回撤11%,夏普5.0 | 金融量化多智能体架构方案
  • 开源AI模型与虚拟世界构建技术前沿
  • 软件缺失dmview.ocx文件 免费下载修复
  • 洛谷 P7518
  • 【学习笔记】线段树合并
  • 2025年采购必看:高口碑快速卷帘门品牌榜单,洁净车间工程/洁净工作台/FFU/净化工作台/医疗装修工程/洁净棚/货淋室快速卷帘门厂商哪个好 - 品牌推荐师
  • 软件工程期末高频易错点深度剖析:避开这些坑,你就赢了!
  • Windows系统文件dpx.dll损坏或丢失 下载修复
  • 基于ARMCortex-M4F内核的MSP432MCU开发实践【1.5】
  • still ace