news 2026/5/1 9:09:22

LeetCode 3652: 按策略买卖股票的最佳时机

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LeetCode 3652: 按策略买卖股票的最佳时机

题目理解

给定价格数组prices和策略数组strategy,策略可以是:

  • -1: 买入
  • 0: 持有
  • 1: 卖出

利润 = Σ(strategy[i] × prices[i])

我们可以进行最多一次修改:选择连续 k 个元素,前 k/2 个改为 0,后 k/2 个改为 1。

求最大可能利润。

解题思路

方法一:暴力枚举(朴素思路)

最直接的想法是枚举所有可能的修改位置:

  • 不修改的情况
  • 从索引 0, 1, 2, …, n-k 开始修改

每次计算修改后的总利润,取最大值。

时间复杂度: O(n²) - 枚举 O(n) 个位置,每次重新计算总利润 O(n)

方法二:前缀和优化(推荐)

观察到暴力方法有大量重复计算。我们可以用前缀和优化。

核心思想

设原始利润为base = Σ(strategy[i] × prices[i])

当我们修改从位置 i 开始的 k 个元素时:

修改前: [i, i+1, ..., i+k/2-1, i+k/2, ..., i+k-1] 修改后: [ 全部变成0 ][ 全部变成1 ]

设:

  • p1 = i,p2 = i + k/2 - 1(前半部分,变成 0)
  • p3 = i + k/2,p4 = i + k - 1(后半部分,变成 1)

则:

  • 原利润在 [p1, p2] 区间:base1 = Σ(strategy[j] × prices[j]),修改后变为 0
  • 原利润在 [p3, p4] 区间:base2 = Σ(strategy[j] × prices[j]),修改后变为Σprices[j]

关键公式

新利润 = base - base1 - base2 + Σprices[p3~p4]

即:

profit_diff = Σprices[p3~p4] - base1 - base2

只有当profit_diff > 0时,修改才能提升利润。

前缀和预处理

使用两个前缀和数组:

  1. prefixSums[i]: prices 的前缀和,用于快速计算价格区间和
  2. baseSums[i]: strategy[j] × prices[j] 的前缀和,用于快速计算原利润

这样每次查询区间和的时间从 O(k) 降到 O(1)。

时间复杂度: O(n) - 预处理 O(n),枚举 O(n) 个位置,每次 O(1) 计算

空间复杂度: O(n)

代码实现

funcmaxProfit(prices[]int,strategy[]int,kint)int64{n:=len(prices)// 前缀和预处理prefixSums:=make([]int64,n+1)// prices 的前缀和baseSums:=make([]int64,n+1)// strategy[i]*prices[i] 的前缀和varbaseint64fori:=0;i<n;i++{prefixSums[i+1]=prefixSums[i]+int64(prices[i])base+=int64(strategy[i])*int64(prices[i])baseSums[i+1]=baseSums[i]+int64(strategy[i])*int64(prices[i])}// 边界:k > n 时无法修改ifk>n{returnbase}maxProfit:=base// 枚举所有修改起点fori:=0;i<=n-k;i++{p1:=i p2:=i+k/2-1p3:=i+k/2p4:=i+k-1// 原利润中被修改部分的贡献base1:=baseSums[p2+1]-baseSums[p1]base2:=baseSums[p4+1]-baseSums[p3]// 修改后后半部分的贡献(全为1)priceSum:=prefixSums[p4+1]-prefixSums[p3]// 新利润 = 原利润 - 被移除部分 + 新增部分profit:=base-base1-base2+priceSumifprofit>maxProfit{maxProfit=profit}}returnmaxProfit}

示例演示

prices = [4,2,8], strategy = [-1,0,1], k = 2为例:

预处理

  • base = (-1)×4 + 0×2 + 1×8 = 4
  • prefixSums = [0, 4, 6, 14]
  • baseSums = [0, -4, -4, 4]

枚举修改位置

  • i=0: 修改 [0,1] → [0,1,1]

    • base1 = baseSums[1] - baseSums[0] = -4
    • base2 = 0 (p3=p4+1)
    • priceSum = prefixSums[2] - prefixSums[1] = 2
    • profit = 4 - (-4) - 0 + 2 =10
  • i=1: 修改 [1,2] → [-1,0,1] (无变化)

    • profit = 4

最大利润: 10

复杂度分析

  • 时间复杂度: O(n),其中 n 是数组长度
  • 空间复杂度: O(n),用于存储前缀和数组

总结

本题的关键是识别暴力枚举中的重复计算,通过前缀和实现 O(1) 的区间和查询,将时间复杂度从 O(n²) 优化到 O(n)。这是一个典型的「暴力→优化」的思维过程。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 8:42:53

实现异构Agent高效协作(基于语义对齐与协议协商的创新方案)

第一章&#xff1a;跨领域 Agent 的协同机制在分布式人工智能系统中&#xff0c;跨领域 Agent 协同机制是实现复杂任务分工与资源整合的核心。多个具备不同专业能力的 Agent 需要在异构环境中达成共识、共享状态并协调行为&#xff0c;以完成单一 Agent 无法独立解决的任务目标…

作者头像 李华
网站建设 2026/5/1 5:01:11

java多线程

一、先搞懂&#xff1a;什么是 Java 多线程&#xff1f;可以把进程想象成一个正在运行的应用程序&#xff08;比如你的微信&#xff09;&#xff0c;而线程是进程里的最小执行单元&#xff08;比如微信同时处理接收消息、显示界面、播放语音&#xff09;。Java 多线程就是让一个…

作者头像 李华
网站建设 2026/5/1 4:51:21

DevOps理念

一、软件开发生命周期&#xff08;SDLC&#xff09;&#xff08;一&#xff09;概述Software Development Life Cycle&#xff08;SDLC&#xff09;是组织和实施软件开发管理的框架&#xff0c;定义系统工程师和开发人员在软件开发和维护中的工作阶段&#xff0c;主要包括需求收…

作者头像 李华
网站建设 2026/4/30 14:33:21

C语言初学者指南:掌握if语句,开启智能编程之旅

引言&#xff1a;为什么if语句如此重要&#xff1f; 作为一名C语言初学者&#xff0c;你刚刚迈入了编程世界中最激动人心的部分——让程序"思考"和"决策"。if语句是编程中的决策点&#xff0c;就像生活中的选择一样&#xff1a;如果下雨了&#xff0c;我就…

作者头像 李华
网站建设 2026/4/30 9:44:41

ECON-023100控制器

ECON-023100 控制器 产品应用领域&#xff1a;工业自动化&#xff1a;用于生产线、加工设备和机器人系统的集中控制与监控。能源管理&#xff1a;电力分配、发电机组和可再生能源系统的运行优化与调度。建筑自动化&#xff1a;智能楼宇管理系统&#xff0c;包括空调、照明、电梯…

作者头像 李华
网站建设 2026/4/29 0:39:09

PKS-60-0019电源模块

PKS-60-0019 电源模块 产品特点&#xff1a;高功率输出提供稳定的大功率直流输出&#xff0c;适合工业设备和高负载应用。宽输入电压范围可兼容不同电源环境&#xff0c;提高系统适应性和灵活性。高效率设计能量转换效率高&#xff0c;降低发热和能耗&#xff0c;支持长时间稳定…

作者头像 李华