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

leetCode每日一题:按策略买卖股票的最佳时机

下面我把LeetCode 3652:按策略买卖股票的最佳时机
完整做一遍:从建模 → 思路 → 算法 → 代码(含详细注释),一步一步来。
原题
给你两个整数数组 prices 和 strategy,其中:

prices[i] 表示第 i 天某股票的价格。 strategy[i] 表示第 i 天的交易策略,其中: -1 表示买入一单位股票。 0 表示持有股票。 1 表示卖出一单位股票。 同时给你一个 偶数 整数 k,你可以对 strategy 进行 最多一次 修改。一次修改包括: 选择 strategy 中恰好 k 个 连续 元素。 将前 k / 2 个元素设为 0(持有)。 将后 k / 2 个元素设为 1(卖出)。 利润 定义为所有天数中 strategy[i] * prices[i] 的 总和 。 返回你可以获得的 最大 可能利润。

注意: 没有预算或股票持有数量的限制,因此所有买入和卖出操作均可行,无需考虑过去的操作 做出这道题,并给出详细解释,分析,和注释

一、题意重述(用“数学 + 业务”语言)

给定:

  • prices[i]:第i天股价

  • strategy[i]:第i天策略

    • -1:买入 → 对利润贡献-prices[i]
    • 0:持有 → 贡献0
    • 1:卖出 → 贡献+prices[i]

原始利润

[
profit = \sum strategy[i] \times prices[i]
]


你可以做最多一次修改

修改规则:

  • 选一个长度为k连续子数组
  • k/2天 → 全部改成0
  • k/2天 → 全部改成1

⚠️k偶数


目标

修改 0 次或 1 次,使总利润最大


二、关键思维:问题本质是什么?

1️⃣ 原利润是固定的

baseProfit = Σ strategy[i] * prices[i]

我们只需要关心:

“一次修改,最多能额外增加多少利润”


2️⃣ 修改 = 对一段区间的“利润差值”

设修改区间是[l, r],长度k
其中:

  • [l, l + k/2 - 1]→ 改为0
  • [l + k/2, r]→ 改为1
原贡献
Σ strategy[i] * prices[i]
新贡献
前半段:0 后半段:+prices[i]
增量 = 新 - 原

三、把“增量”拆成两个部分

🔹 前半段(变成 0)

原来:strategy[i] * prices[i] 现在:0 增量:- strategy[i] * prices[i]

🔹 后半段(变成卖出)

原来:strategy[i] * prices[i] 现在:+prices[i] 增量:(1 - strategy[i]) * prices[i]

✅ 单次修改的总增量

[
\Delta =
\sum_{前半段} (-strategy[i] \cdot prices[i])
+
\sum_{后半段} ((1 - strategy[i]) \cdot prices[i])
]


四、算法思路(滑动窗口)

为什么用滑动窗口?

  • 区间长度固定为k
  • 要枚举所有连续长度为k的区间
  • 每次移动只加减一个元素

👉O(n)


核心变量

  • baseProfit:不修改的利润
  • delta:当前窗口的利润增量
  • maxDelta:所有窗口中最大的增量

滑动时怎么更新?

设当前窗口[i - k + 1, i]

新进入的元素i

  • i在后半段 → 加(1 - strategy[i]) * prices[i]

移出的元素i - k

  • 若它原来在前半段 → 减-strategy[x] * prices[x]
  • 若在后半段 → 减(1 - strategy[x]) * prices[x]

五、完整 Java 实现(带详细注释)

classSolution{publiclongmaxProfit(int[]prices,int[]strategy,intk){intn=prices.length;// 1. 计算原始利润longbaseProfit=0;for(inti=0;i<n;i++){baseProfit+=(long)strategy[i]*prices[i];}// 如果 k 为 0 或无法修改if(k==0||k>n){returnbaseProfit;}inthalf=k/2;longdelta=0;longmaxDelta=0;// 2. 初始化第一个窗口 [0, k-1]for(inti=0;i<k;i++){if(i<half){// 前半段 → 变成 0delta+=-(long)strategy[i]*prices[i];}else{// 后半段 → 变成卖出delta+=(long)(1-strategy[i])*prices[i];}}maxDelta=Math.max(0,delta);// 3. 滑动窗口for(inti=k;i<n;i++){intout=i-k;// 移除 outif(out<out+half){delta-=-(long)strategy[out]*prices[out];}else{delta-=(long)(1-strategy[out])*prices[out];}// 加入 iif(i<out+k-half){delta+=-(long)strategy[i]*prices[i];}else{delta+=(long)(1-strategy[i])*prices[i];}maxDelta=Math.max(maxDelta,delta);}// 4. 原始利润 + 最佳增量returnbaseProfit+maxDelta;}}

六、复杂度分析

项目复杂度
时间O(n)
空间O(1)

七、为什么这题是「中等」但难度偏高?

  1. 题目描述是业务语言

  2. 真正考的是:

    • 数学建模能力
    • 把“策略变化”转为“区间增量”
  3. 很多人卡在:

    • 不知道“利润增量”怎么计算
    • 想 DP,其实不需要

http://www.cnnetsun.cn/news/128106.html

相关文章:

  • 招标平台最难的战斗:在持续变化中保持数据稳定与精准
  • 洋驼帮跨境物流
  • 前后端分离滑雪场管理系统系统|SpringBoot+Vue+MyBatis+MySQL完整源码+部署教程
  • Kotaemon在政务场景下的合规性与安全性设计
  • 两款免费神器一键修复,网络难题轻松搞定!
  • 自动化营销有哪些方式,国内外有哪些自动化营销工具?
  • Cursor快捷键大全:效率翻倍的隐藏技巧
  • 【项目实战】md 是标准纯文本标记语言,mdx 是其扩展格式(融合 JSX/组件能力)
  • 2、网络指南:印刷版与在线版的选择及网络知识介绍
  • Kotaemon如何处理歧义问题?上下文消解策略解析
  • 6、网络配置与管理全解析
  • 零代码训练!用本地大模型实现文本情感分析
  • Kotaemon备份与恢复策略:防止数据丢失
  • 批量将 Word 文档重命名为其标题
  • Kotaemon本地部署教程:保护数据隐私的新选择
  • Kotaemon支持GraphQL接口吗?现代API集成方案
  • 基于Kotaemon的政策法规智能查询系统
  • Kotaemon前缀缓存机制:加速重复查询响应
  • 42、数据绑定中的错误处理与ASP.NET数据绑定实践
  • 46、WinFx数据绑定入门指南
  • Kotaemon危机公关声明撰写:负面舆情应对
  • Kotaemon如何生成参考文献?学术写作辅助新玩法
  • 12、深入解析词法分析与语法分析工具的核心功能
  • 13、Bison 解析器的高级特性与使用技巧
  • Kotaemon中的元数据过滤功能如何精准定位内容?
  • 部署稳定、效果可追踪——Kotaemon RAG框架核心优势
  • Kotaemon签证政策实时查询系统
  • 请编写一个 Shell 脚本监控系统的 CPU 使用率(中等)
  • SpringBoot+Vue html+css在线英语阅读分级平台管理平台源码【适合毕设/课设/学习】Java+MySQL
  • Kotaemon在制造业的应用探索:设备故障智能诊断