news 2026/8/30 19:52:37

day162—递归—买卖股票的最佳时机Ⅱ(LeetCode-122)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
day162—递归—买卖股票的最佳时机Ⅱ(LeetCode-122)

题目描述

给你一个整数数组prices,其中prices[i]表示某支股票第i天的价格。

在每一天,你可以决定是否购买和/或出售股票。你在任何时候最多只能持有一股股票。然而,你可以在同一天多次买卖该股票,但要确保你持有的股票不超过一股。

返回你能获得的最大利润

示例 1:

输入:prices = [7,1,5,3,6,4]输出:7解释:在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4。 随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6 - 3 = 3。 最大总利润为 4 + 3 = 7 。

示例 2:

输入:prices = [1,2,3,4,5]输出:4解释:在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4。 最大总利润为 4 。

示例 3:

输入:prices = [7,6,4,3,1]输出:0解释:在这种情况下, 交易无法获得正利润,所以不参与交易可以获得最大利润,最大利润为 0。

提示:

  • 1 <= prices.length <= 3 * 104
  • 0 <= prices[i] <= 104

解决方案:

这段代码是基于记忆化递归的方式求解 “无限次买卖股票的最佳时机” 问题,在你原有递归思路的基础上,仅做了最小化修改(增加记忆化缓存、规范边界值),既保留了核心递归逻辑,又解决了纯递归的超时和栈溢出问题,能高效处理大数据量用例。

核心逻辑

  1. 核心定义

    • memo:二维记忆化数组(len×2),memo[end][0/1]缓存dfs(end, is)的结果(0 = 不持有股票,1 = 持有股票),避免重复递归计算;
    • dfs(end, is, nums):返回从第 0 到第end天,在is状态(true= 持有、false= 不持有)下能获得的最大利润。
  2. 递归边界

    • end < 0(所有天数遍历完毕):
      • is=true(仍持有股票),返回-0xFFFF(极小值,代表非法状态 —— 交易结束时持有股票无利润);
      • is=false(不持有股票),返回 0(无交易时利润为 0)。
  3. 记忆化优化:计算dfs(end, is)前,先检查memo[end][state]state为 0/1 对应不持有 / 持有),若不为 - 1 则直接返回缓存值,避免重复递归。

  4. 状态转移(核心逻辑)

    • 持有股票(is=true):利润取 “继续持有(不操作)” 和 “卖出股票(转为不持有,利润 - 当前股价)” 的最大值;
    • 不持有股票(is=false):利润取 “继续不持有(不操作)” 和 “买入股票(转为持有,利润 + 当前股价)” 的最大值;
    • 计算结果存入memo缓存后返回。
  5. 主函数逻辑:初始化记忆化数组,调用dfs(len-1, false, prices)(从最后一天、不持有股票的初始状态开始计算),返回最终最大利润。

关键特点

  • 最小化修改:完全保留你 “从后往前递归 + 持有 / 不持有状态” 的核心思路,仅增加记忆化和规范边界值;
  • 效率优化:记忆化将时间复杂度从O(2n)降至O(n),解决了大数据量超时 / 栈溢出问题;
  • 逻辑兼容:能正确处理空数组、单调涨跌等边界场景,返回合理的最大利润。

总结

  1. 核心思路:在你原有递归逻辑基础上,通过记忆化缓存避免重复计算,是对纯递归的高效优化;
  2. 关键设计:用二维数组缓存(end, 持有/不持有)状态的结果,是递归优化的核心;
  3. 功能效果:能稳定通过 n=60 甚至更大的股票价格数组用例,返回正确的最大利润。

函数源码:

class Solution { public: vector<vector<int>> memo; // 仅修改该函数:增加记忆化+修正状态转移符号+规范边界值 int dfs(int end, bool is, vector<int>& nums) { int len = nums.size(); if(end < 0) { // 边界值修正:用INT_MIN表示持有股票的非法状态,更规范 if(is) return -0xFFFF; return 0; } int state = is ? 1 : 0; // 0=不持有,1=持有 if (memo[end][state] != -1) { return memo[end][state]; } int res; if(is) { res = max(dfs(end-1, true, nums), dfs(end-1, false, nums) - nums[end]); } else { res = max(dfs(end-1, false, nums), dfs(end-1, true, nums) + nums[end]); } // 缓存当前状态的结果 return memo[end][state] = res; } int maxProfit(vector<int>& prices) { int len = prices.size(); if (len == 0) return 0; // 空数组边界处理 // 初始化记忆化数组(len行2列,初始值-1表示未计算) memo.assign(len, vector<int>(2, -1)); // max(0, ...) 确保利润不会为负(无交易时利润为0) return dfs(len-1, false, prices); } };
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/29 9:33:40

边界之内:为何高维内插无法催生下一次科学革命?

在一个被大数据和人工智能的承诺所笼罩的时代&#xff0c;一种信念日益深入人心&#xff1a;只要有足够的数据和强大的算法&#xff0c;我们就能自动解锁自然界最深邃的奥秘。机器学习模型在蛋白质折叠、材料发现和气候预测等领域取得的惊人成就&#xff0c;似乎都在为这一愿景…

作者头像 李华
网站建设 2026/8/29 12:47:20

Spring Boot 三种方式登录系统:集成微信扫码、短信验证码、邮箱验证码

Spring Boot 三种方式登录系统&#xff1a;集成微信扫码、短信验证码、邮箱验证码&#xff08;含高并发与安全增强&#xff09; 主要因为前面的帖子不太完整。 一、引言 在现代 Web 应用中&#xff0c;提供多种灵活、安全的登录方式已成为标配。本文档旨在提供一套生产就绪的…

作者头像 李华
网站建设 2026/8/19 22:11:57

HTML5 与 H5:别再让你的专业度在称呼中流失

在中国互联网行业的日常交流中&#xff0c;很少有一个词像“H5”这样被高频使用&#xff0c;却又被如此普遍地误解。当你听到有人说“做一个 H5”时&#xff0c;对方指的往往是一个在微信朋友圈传播的精美幻灯片&#xff0c;或者是一个简单的营销小游戏。然而&#xff0c;当你打…

作者头像 李华
网站建设 2026/8/28 5:39:31

3-VueAjax

什么是Vue Vue是一款用于构建用户界面的渐进式的JavaScript框架。官方网站&#xff1a;https://cn.vuejs.org/ 前端负责将数据以美观的样式呈现出来&#xff0c;而数据最终又要在数据库服务器中存储并管理。前端想要拿到数据&#xff0c;就需要请求服务器。然后服务器将数据返…

作者头像 李华
网站建设 2026/8/27 22:50:24

基于springBoot的房屋租赁管理系统

房屋租赁管理系统的背景意义 市场需求驱动 随着城市化进程加快&#xff0c;流动人口增多&#xff0c;房屋租赁需求持续增长。传统租赁方式依赖中介或线下沟通&#xff0c;效率低且信息不透明。数字化管理系统能优化流程&#xff0c;提升供需匹配效率&#xff0c;降低交易成本…

作者头像 李华
网站建设 2026/8/29 6:02:35

Java基于SSM+JSP的智慧农业无人机租赁系统的设计与实现

项目说明 农业无人机是一种在现代农业中广泛应用的无人机设备&#xff0c;它可以通过遥控或自主飞行&#xff0c;进行一系列农业作业。这些无人机通常配备有高分辨率相机和绘图设备&#xff0c;可以用于进行土地勘测、作物评估、农药喷洒等农业活动。无人机在农业领域的应用&am…

作者头像 李华