← 返回编程题库
coding-min-cuts-stable-spread-runs中等免费版2000ms未尝试

波动稳定段切分 —— 在跨度上限下覆盖收益序列的最少段数

Regime-Stability Segmentation — Fewest Bounded-Spread Runs Over A Return Stream

开始编码

实现 solution(returns: list[float], delta_max: float) -> int。给定长度为 N 的每期收益序列与非负跨度上限 delta_max,将其划分为最少数量的连续、不重叠,使每段的段内跨度 max(段) - min(段) 都不超过 delta_max。返回这一最少段数。

从左到右单遍贪心:维护当前段的 running_maxrunning_min;若并入 returns[i] 会令 max(running_max, returns[i]) - min(running_min, returns[i]) > delta_max,则在 i开新段(重置 running_max = running_min = returns[i]);否则把 returns[i] 并入当前段。贪心最优:当前段尽量向右延伸不会逼后续段付出更多切分成本。

示例矩阵:

  • solution([], 0.10) 返回 0(空数组用零段覆盖)。
  • solution([0.5], 1.0) 返回 1(单元素,跨度 0 <= 1.0)。
  • solution([0.1, 0.1, 0.1, 0.1], 0.0) 返回 1delta_max = 0 允许常值段;整段跨度 0)。
  • solution([1.0, 2.0, 3.0, 4.0], 0.0) 返回 4delta_max = 0 且全互异,每元素独立一段)。
  • solution([0.01, 0.02, 0.05, -0.01, -0.02, 0.04, 0.05], 100.0) 返回 1(cap 极大,整段一段)。

solution([0.01, 0.02, 0.05, -0.01, -0.02, 0.04, 0.05], 0.05) 返回 3。从左到右扫描,cap 0.05。下标 0 起首段,running_max = running_min = 0.01。下标 10.02):试探跨度 0.02 - 0.01 = 0.01 <= 0.05,并入。下标 20.05):跨度 0.05 - 0.01 = 0.04 <= 0.05,并入。下标 3-0.01):试探跨度 0.05 - (-0.01) = 0.06 > 0.05 —— 在下标 3 起新段,running_max = running_min = -0.01。下标 4-0.02):跨度 (-0.01) - (-0.02) = 0.01,并入。下标 50.04):试探跨度 0.04 - (-0.02) = 0.06 > 0.05 —— 在下标 5 起新段,running_max = running_min = 0.04。下标 60.05):跨度 0.05 - 0.04 = 0.01,并入。共 3 段。

实践背景

研究台为每条回测策略输出一项"波动稳定性"概览指标:扫描日收益序列,统计将其端到端覆盖所需的最少连续有界跨度段数,其中每段的段内跨度(段内日收益的 max - min)必须不超过台子统一容差 delta_max(每个资产类一个值,按典型节内分散度校准)。该计数小,意味着策略大体停留在同一波动率区间;该计数大,意味着日收益分布频繁切换 —— 风险台视为红旗,因为下游风险模型按区间校准,区间频繁切换会失效。"最少段数"的形式化是台子规则:度量本身就是这个计数,因此把每段尽量向右延伸的左到右贪心刚好是风险台想要的。无失败哨兵:任何序列都存在合法划分(最坏情形每元素一段),返回值始终是非负整数。

实现细节由 stubs/stub.py 提供。

约束条件

  • 0 <= N <= 5000,其中 N 为 solution(returns, delta_max) 的 returns 输入长度
  • 0 <= delta_max <= 2e6,单段允许的最大跨度(任一连续段内 `max - min`)
  • 每个 returns[i] 为有限浮点数,-1e6 <= returns[i] <= 1e6(**每期收益率**,不是价格)
  • 段合法当且仅当 `max(段) - min(段) <= delta_max`(含等号);切分触发条件为严格 `new_max - new_min > delta_max`(不引入任何 epsilon 容差)
  • 返回类型为 int。划分必须**覆盖**整个数组 —— `[0, N)` 中每个下标恰属于一个段,段间连续不重叠。空 returns 返回 0;单元素返回 1;无失败哨兵(答案恒为非负整数)

样例

Case 1 · statement-example: spread cap forces 3 runs

输入: [[0.01,0.02,0.05,-0.01,-0.02,0.04,0.05],0.05]

期望: 3

依次扫描,合并到 0.05 时跨度 0.04<=0.05;遇 -0.01 跨度 0.06>0.05 切;再遇 0.04 跨度 0.06>0.05 切;共 3 段。

Case 2 · statement-example: empty input returns 0

输入: [[],0.1]

期望: 0

空数组无任何元素,按零段覆盖,返回 0。

Case 3 · statement-example: single element returns 1

输入: [[0.5],1]

期望: 1

单元素跨度 0<=delta_max,构成一段。

Case 4 · statement-example: delta_max=0 with all-equal cluster returns 1

输入: [[0.1,0.1,0.1,0.1],0]

期望: 1

所有元素相等,整段跨度 0<=0;单段。

Case 5 · statement-example: delta_max=0 strictly distinct returns N

输入: [[1,2,3,4],0]

期望: 4

delta_max=0 强制每段为常值;元素互不相等,必须每元素一段,返回 4。

Case 6 · statement-example: huge delta_max collapses to 1 run

输入: [[0.01,0.02,0.05,-0.01,-0.02,0.04,0.05],100]

期望: 1

整体最大-最小=0.07<=100,整段一段。

最近提交

还没有提交记录。

编码区

实现 solution(...)。本地运行当前支持 Python 可见样例;服务端提交会运行可见样例和隐藏测试。

加载编辑器...
计时0:00

默认展示公开样例。点击「运行样例」后会在这里显示实际输出;点击「提交评测」会进入隐藏测试。

Case 1 · statement-example: spread cap forces 3 runs

输入: [[0.01,0.02,0.05,-0.01,-0.02,0.04,0.05],0.05]

期望: 3

依次扫描,合并到 0.05 时跨度 0.04<=0.05;遇 -0.01 跨度 0.06>0.05 切;再遇 0.04 跨度 0.06>0.05 切;共 3 段。

Case 2 · statement-example: empty input returns 0

输入: [[],0.1]

期望: 0

空数组无任何元素,按零段覆盖,返回 0。

Case 3 · statement-example: single element returns 1

输入: [[0.5],1]

期望: 1

单元素跨度 0<=delta_max,构成一段。

Case 4 · statement-example: delta_max=0 with all-equal cluster returns 1

输入: [[0.1,0.1,0.1,0.1],0]

期望: 1

所有元素相等,整段跨度 0<=0;单段。

Case 5 · statement-example: delta_max=0 strictly distinct returns N

输入: [[1,2,3,4],0]

期望: 4

delta_max=0 强制每段为常值;元素互不相等,必须每元素一段,返回 4。

Case 6 · statement-example: huge delta_max collapses to 1 run

输入: [[0.01,0.02,0.05,-0.01,-0.02,0.04,0.05],100]

期望: 1

整体最大-最小=0.07<=100,整段一段。