下一个更小元素的下标
Next Smaller Element Index
开始编码某个 tick 数据分析流水线在回放一段与价格相关的序列 nums(例如中间价、最后成交价或一段按等距时间戳采样的衍生信号)。对每个位置 i,桌组想知道取值下一次严格走低需要多久——具体来说,找到下标最小的、值严格小于 nums[i] 的后续采样,并返回其下标;若到序列末尾都没有任何后续采样跌破 nums[i],则返回 -1。这种「下一次下跳查找」是微观结构分析的基础原语:它是逆向选择诊断(「我在第 i 个采样挂出被动买单后,过几个 tick 中间价会打到我下方?」)和时间-到-反转直方图的底层算子,常用于调校被动报价的持仓时长。
请实现 solution(nums: list[int]) -> list[int]。返回一个与 nums 等长的整数列表;第 i 项是下一个值严格小于 nums[i] 的采样的下标(不是值本身),若不存在则为 -1。空输入返回 []。
示例 1(典型混合用例):solution([3, 1, 4, 1, 5, 9, 2, 6]) 返回 [1, -1, 3, -1, 6, 6, -1, -1]。下标 0(值 3)首次被打破是在下标 1(值 1);下标 1(值 1)之后再没有出现过严格更小的值 → -1;下标 2(值 4)→ 下标 3(值 1);下标 3(值 1)→ -1;下标 4(值 5)→ 下标 6(值 2);下标 5(值 9)→ 下标 6(值 2);下标 6、7 之后没有严格更小者 → -1。
示例 2(严格递减——每个下标都在 i+1 解决):solution([5, 4, 3, 2, 1]) 返回 [1, 2, 3, 4, -1]。每个值都立刻被它右边的邻居打破;最后一个没有后继。
示例 3(全相等——严格小于下没有任何下标会被解决):solution([7, 7, 7]) 返回 [-1, -1, -1]。这些值全部相等,从来没有「严格更小」过——「严格小于」语义下相等的值不能互相解决对方。这就是把比较条件错写成 ≥ 时最容易踩的坑:那样会让下标 0 错误地在下标 1 被解决。
朴素的双重循环是 O(N²),N = 10⁵ 时必超时。正确工具是一个单调递增栈,栈里存放还没找到答案的下标。从左到右扫一遍,对每个新值 v:弹出所有栈顶值 > v 的下标(这些下标的「下一个更小」恰好就是当前下标,弹出时一并写入答案),然后把当前下标压栈。栈中元素从底到顶始终保持「值严格递增」,每个下标至多被压入和弹出一次 → O(N) 摊还时间,O(N) 额外空间。弹出条件用严格大于(> 而非 ≥)正是让相等元素不互相解决的关键。
约束条件
- 0 ≤ N = len(nums) ≤ 100000
- -10^9 ≤ nums[i] ≤ 10^9(每个元素都是整数)
- 返回长度为 N 的列表;第 i 项是 i 右侧第一个严格更小元素的下标,若不存在则为 -1
- 空输入返回 []
样例
Case 1 · empty input
输入: [[]]
期望: []
空序列直接返回空列表。
Case 2 · single element — no successor, returns [-1]
输入: [[42]]
期望: [-1]
只有一个元素,后面没有任何采样,自然不存在「下一个更小」,返回 [-1]。
Case 3 · mixed sample from problem statement
输入: [[3,1,4,1,5,9,2,6]]
期望: [1,-1,3,-1,6,6,-1,-1]
下标 0(值 3)→下标 1(值 1);下标 1 之后没有更小者→-1;下标 2(值 4)→下标 3(值 1);下标 3→-1;下标 4(值 5) 与 下标 5(值 9) 都在下标 6(值 2) 被打破;下标 6、7 之后无更小者。
Case 4 · monotonic decreasing — each resolves at i+1
输入: [[5,4,3,2,1]]
期望: [1,2,3,4,-1]
严格递减,每个值都立刻被右邻居打破,最后一个没有后继返回 -1。
Case 5 · monotonic increasing — never resolves, all -1
输入: [[1,2,3,4,5]]
期望: [-1,-1,-1,-1,-1]
严格递增,后续永远没有更小者,全部返回 -1。
Case 6 · all-equal — strict-smaller never holds, all -1
输入: [[7,7,7]]
期望: [-1,-1,-1]
全相等;严格小于下没有任何对象会被解决,全部返回 -1。
Case 7 · two equal elements
输入: [[4,4]]
期望: [-1,-1]
两个相等元素,严格小于不成立,返回 [-1, -1]。
Case 8 · negatives, zero, positives interleaved
输入: [[-3,0,-5,2,-1,-10,5]]
期望: [2,2,5,4,5,-1,-1]
覆盖正负与零交错的情形,验证比较是按整数大小而非绝对值。
Case 9 · boundary ints near ±1e9
输入: [[1000000000,-1000000000,1000000000,-1000000000,0]]
期望: [1,-1,3,-1,-1]
覆盖约束上下界 ±1e9 与 0 的混合,验证不依赖小整数假设。
Case 10 · plateau then strict drop
输入: [[5,5,5,2,5,5,1]]
期望: [3,3,3,6,6,6,-1]
前段平台同值不互相解决;下标 0~2 都在下标 3(值 2) 被打破;下标 4、5 在下标 6(值 1) 被打破。
Case 11 · V-shape — descending then ascending
输入: [[10,7,4,1,4,7,10]]
期望: [1,2,3,-1,-1,-1,-1]
下行段每步都被打破;上行段无更小者全部 -1,除了最低点 1 也没有后继。
最近提交
还没有提交记录。
编码区
实现 solution(...)。本地运行当前支持 Python 可见样例;服务端提交会运行可见样例和隐藏测试。
默认展示公开样例。点击「运行样例」后会在这里显示实际输出;点击「提交评测」会进入隐藏测试。
Case 1 · empty input
输入: [[]]
期望: []
空序列直接返回空列表。
Case 2 · single element — no successor, returns [-1]
输入: [[42]]
期望: [-1]
只有一个元素,后面没有任何采样,自然不存在「下一个更小」,返回 [-1]。
Case 3 · mixed sample from problem statement
输入: [[3,1,4,1,5,9,2,6]]
期望: [1,-1,3,-1,6,6,-1,-1]
下标 0(值 3)→下标 1(值 1);下标 1 之后没有更小者→-1;下标 2(值 4)→下标 3(值 1);下标 3→-1;下标 4(值 5) 与 下标 5(值 9) 都在下标 6(值 2) 被打破;下标 6、7 之后无更小者。
Case 4 · monotonic decreasing — each resolves at i+1
输入: [[5,4,3,2,1]]
期望: [1,2,3,4,-1]
严格递减,每个值都立刻被右邻居打破,最后一个没有后继返回 -1。
Case 5 · monotonic increasing — never resolves, all -1
输入: [[1,2,3,4,5]]
期望: [-1,-1,-1,-1,-1]
严格递增,后续永远没有更小者,全部返回 -1。
Case 6 · all-equal — strict-smaller never holds, all -1
输入: [[7,7,7]]
期望: [-1,-1,-1]
全相等;严格小于下没有任何对象会被解决,全部返回 -1。
Case 7 · two equal elements
输入: [[4,4]]
期望: [-1,-1]
两个相等元素,严格小于不成立,返回 [-1, -1]。
Case 8 · negatives, zero, positives interleaved
输入: [[-3,0,-5,2,-1,-10,5]]
期望: [2,2,5,4,5,-1,-1]
覆盖正负与零交错的情形,验证比较是按整数大小而非绝对值。
Case 9 · boundary ints near ±1e9
输入: [[1000000000,-1000000000,1000000000,-1000000000,0]]
期望: [1,-1,3,-1,-1]
覆盖约束上下界 ±1e9 与 0 的混合,验证不依赖小整数假设。
Case 10 · plateau then strict drop
输入: [[5,5,5,2,5,5,1]]
期望: [3,3,3,6,6,6,-1]
前段平台同值不互相解决;下标 0~2 都在下标 3(值 2) 被打破;下标 4、5 在下标 6(值 1) 被打破。
Case 11 · V-shape — descending then ascending
输入: [[10,7,4,1,4,7,10]]
期望: [1,2,3,-1,-1,-1,-1]
下行段每步都被打破;上行段无更小者全部 -1,除了最低点 1 也没有后继。