距离下一次新高的索引:首个严格高于「累积最高水位」的未来 tick
Time-to-New-All-Time-High: First Future Index Strictly Above the Running Peak
开始编码实现 solution(prices: list[float]) -> list[int]。给定长度为 N 的价格序列 prices,对每个下标 i(0 <= i < N)返回首个未来 tick j > i,使得 prices[j] 严格大于此前(含 i)的累积最高水位,即 prices[j] > max(prices[0..i])。若不存在这样的 j,该位返回 -1。输出是长度为 N 的 list[int]。
每个下标 i 处的阈值是包含 i 在内的累积最高水位 peak[i] = max(prices[0..i]),而不是 prices[i]。当 prices[i] 处在回撤段(低于此前峰值)时,问题问的仍然是「未来何时首次严格突破水位」。这正是与一般 next greater element(LC 496 / LC 503)以及 LC 739 / LC 901 的核心区别——后几者都用 prices[i] 自身作为阈值,而这里的阈值是关于 i 单调不降的累积最大值。
例
solution([3.0, 1.0, 4.0, 1.0, 5.0, 9.0, 2.0, 6.0]) 返回 [2, 2, 4, 4, 5, -1, -1, -1]。累积最高水位序列为 [3, 3, 4, 4, 5, 9, 9, 9]:在 i = 0 和 i = 1,阈值是 3,首个严格大于 3 的未来 tick 是 j = 2(价格 4.0);在 i = 2 和 i = 3,阈值升到 4,首个严格大于 4 的未来 tick 是 j = 4(价格 5.0);在 i = 4 阈值 5,对应 j = 5(9.0);在 i = 5, 6, 7 阈值是全局峰值 9.0,未来没有任何 tick 严格大于 9.0,故为 -1。注意 i = 1 和 i = 3 这两个回撤段中的 tick 与上一位共享答案,正是因为阈值是累积水位、而不是局部价格。
需要明确的细节:空输入返回空列表;长度为 1 时输出 [-1](没有未来);与累积最高水位的比较是严格的(>),相等于水位不算——常数序列以及最大值出现在下标 0 之后再也不被严格突破的序列,结果都是全 -1;输出列表按位置 精确 比较(整数比较,不带浮点容差)。
朴素双重循环(对每个 i 计算 peak[i] 再向后线性扫)最坏 O(N^2),会在 N 接近上限的隐藏用例上超时(例如长串严格递减后在最末端出现一次严格新高——前缀里每个下标都要扫到末尾)。标准做法是两遍 O(N):先用一次左到右扫描预计算 peak[i] = max(prices[0..i]),再用右到左单调栈维护未来候选下标(栈中价格自底向顶严格递减),处理每个 i 时弹掉所有不可能严格超过 peak[i] 的栈顶。
实现细节由 stubs/stub.py 提供。
实践背景
研究侧对一条策略权益曲线或合成价 tape 的常用诊断之一就是距离下一次新高的时间:在每个 tick i,距离曲线下一次出现「全历史新高」还差几个 tick?回撤的两个互补面是回撤深度与回撤+恢复时长,这条索引序列直接给出了恢复一侧——下游工具把差值 j - i(或 j = -1、即样本期内永不恢复时记为 +∞)聚合成一份「恢复延时分布」,用于容量评估与风控滤镜。把阈值定为累积最高水位而不是逐 tick 价格,恰好对齐桌面侧直觉:要被「夺回」的是水位,而不是回撤途中的当前价;因此一段长而浅的回撤里所有 tick 通常会映射到同一个恢复下标。严格不等号(> 而非 >=)也是有意为之:与水位持平并不构成新高,只有严格更高的 print 才能重置「高水位周期」。这条 time-to-new-high 序列与 trailing-span / 回撤深度等诊断配合,可以让研究 notebook 不必从每个 tick 重扫整段 tape 就直接画出跨制度的恢复直方图——这正是工程上必须把暴力 O(N²) 双重循环压成均摊 O(N) 的原因。
约束条件
- 0 <= N <= 200000,其中 N 为 solution(prices) 的输入长度
- 每个 prices[i] 为 -1e9 到 1e9 之间的浮点数
- 输出为长度为 N 的 list[int],第 i 项为首个满足 j > i 且 prices[j] > max(prices[0..i]) 的下标 j;若不存在则为 -1
- 与「累积最高水位」的比较为**严格大于**(>),相等不算
- 输出按位置精确比对(exact 比较),不允许浮点容差
样例
Case 1 · statement-example: peak-relative next high
输入: [[3,1,4,1,5,9,2,6]]
期望: [2,2,4,4,5,-1,-1,-1]
running peak 序列为 [3,3,4,4,5,9,9,9]:i=0/1 阈值 3,下一个严格大于 3 的位置是 j=2;i=2/3 阈值 4,下一个 j=4;i=4 阈值 5 下一个 j=5;i=5/6/7 阈值 9,无后续严格更高,故 -1。
Case 2 · visible: ties don't count, must be strict
输入: [[2,1,2,3]]
期望: [3,3,3,-1]
peak=[2,2,2,3];i=0 阈值 2,prices[2]=2 不算(必须严格大于),首个严格 > 2 的是 j=3;i=3 后无未来 tick,-1。
Case 3 · visible: dip below peak still asks about peak
输入: [[5,1,6]]
期望: [2,2,-1]
peak=[5,5,6];i=1 时 prices[1]=1 但阈值是 peak[1]=5(不是 prices[1]!),prices[2]=6>5 故 j=2。
最近提交
还没有提交记录。
编码区
实现 solution(...)。本地运行当前支持 Python 可见样例;服务端提交会运行可见样例和隐藏测试。
默认展示公开样例。点击「运行样例」后会在这里显示实际输出;点击「提交评测」会进入隐藏测试。
Case 1 · statement-example: peak-relative next high
输入: [[3,1,4,1,5,9,2,6]]
期望: [2,2,4,4,5,-1,-1,-1]
running peak 序列为 [3,3,4,4,5,9,9,9]:i=0/1 阈值 3,下一个严格大于 3 的位置是 j=2;i=2/3 阈值 4,下一个 j=4;i=4 阈值 5 下一个 j=5;i=5/6/7 阈值 9,无后续严格更高,故 -1。
Case 2 · visible: ties don't count, must be strict
输入: [[2,1,2,3]]
期望: [3,3,3,-1]
peak=[2,2,2,3];i=0 阈值 2,prices[2]=2 不算(必须严格大于),首个严格 > 2 的是 j=3;i=3 后无未来 tick,-1。
Case 3 · visible: dip below peak still asks about peak
输入: [[5,1,6]]
期望: [2,2,-1]
peak=[5,5,6];i=1 时 prices[1]=1 但阈值是 peak[1]=5(不是 prices[1]!),prices[2]=6>5 故 j=2。