击穿盈利目标的最长子窗口:单调栈解前缀和长度优化
Longest Sub-Window Beating a PnL Target via Monotonic-Stack on Prefix Sums
开始编码实现 solution(pnl: list[float], target_gain: float) -> int。给定一段策略的逐期 PnL 序列 pnl 与一个非负最小盈利目标 target_gain,确定累计 PnL 严格超过 target_gain 的最长连续子段的长度。
例:solution([1.0, -2.0, 3.0, -1.0, 2.0], 2.0) 返回 5。整段累计 PnL = 1 - 2 + 3 - 1 + 2 = 3,严格大于阈值 2.0,因此整个序列就是最长合格段。
如果不存在累计 PnL 严格大于 target_gain 的子段(例如全部为负的序列,或 target_gain 已不小于最佳子段和),返回 zero。注意"超过 target_gain 的最长子段"和"最大和子段"是不同问题:Kadane 解决后者,本题需要前者,且包含负值的混合段完全可能成为答案。
阈值 target_gain 是输入的一部分——比较 P[j] - P[i] > target_gain 不能通过对每期 pnl 做常数偏移化归,因此 target_gain > 0 时是基线"和>0"问题的严格扩展。
实现细节由 stubs/stub.py 提供。
实践背景
在做日内策略归因时,研究员经常需要从一段逐期 PnL 流中识别策略在多长的连续窗口内能稳定击穿某条最低盈利门槛(如手续费预算、基准漂移率或风险底线)——这是刻画策略持续性(regime stability)的常用维度。它与"最大和子段"回答的是不同问题:一个看在阈值约束下的长度,一个看无约束的高度。窗口越长,意味着该策略在此区间内连续的 alpha 既未被瞬时回撤吞掉、又能稳定跑赢门槛;当窗口长度接近全样本时,研究员会继续检查是否存在过拟合或样本外漂移。
约束条件
- 0 <= N <= 5000,其中 N 为 solution(pnl, target_gain) 的输入长度
- 每个 pnl[i] 为有限浮点数,|pnl[i]| <= 1e6
- target_gain 为有限浮点数,0 <= target_gain <= 1e6;比较运算符为**严格大于** target_gain(和恰好等于 target_gain 的子段不计入)
- 若数组为空或不存在和严格大于 target_gain 的子段,返回 zero
- 输出为整数长度,使用精确比对(不引入浮点容差)
样例
Case 1 · statement-example: full window profitable
输入: [[1,-2,3,-1,2],2]
期望: 5
整段累计 PnL = 1 - 2 + 3 - 1 + 2 = 3,严格大于阈值 2.0,因此整个长度 5 的序列就是最长合格段。
Case 2 · statement-example: all-negative returns 0
输入: [[-1,-2,-3],0]
期望: 0
所有元素均为负,前缀和单调下降,不存在和严格大于 0.0 的子段,返回 0。
Case 3 · statement-example: single positive element
输入: [[5],0]
期望: 1
唯一元素 5.0 > 0.0,最长合格段长度 1。
最近提交
还没有提交记录。
编码区
实现 solution(...)。本地运行当前支持 Python 可见样例;服务端提交会运行可见样例和隐藏测试。
默认展示公开样例。点击「运行样例」后会在这里显示实际输出;点击「提交评测」会进入隐藏测试。
Case 1 · statement-example: full window profitable
输入: [[1,-2,3,-1,2],2]
期望: 5
整段累计 PnL = 1 - 2 + 3 - 1 + 2 = 3,严格大于阈值 2.0,因此整个长度 5 的序列就是最长合格段。
Case 2 · statement-example: all-negative returns 0
输入: [[-1,-2,-3],0]
期望: 0
所有元素均为负,前缀和单调下降,不存在和严格大于 0.0 的子段,返回 0。
Case 3 · statement-example: single positive element
输入: [[5],0]
期望: 1
唯一元素 5.0 > 0.0,最长合格段长度 1。