插入并合并订单簿价格档位区间
Insert and Merge Order-Book Price-Level Intervals
开始编码某做市引擎把订单簿维护为一组按 start 升序、两两不相交的价格档位区间,每个 [start, end] 代表做市方愿意在该连续 tick 段以聚合后的统一规模挂单。当一笔新的静止挂单到来时——无论是客户新单还是重定价事件——它会以单个区间 new_level = [s, e] 的形式投递进来。订单簿必须吞入这个新区间,与所有相切或相交的已有档位合并,合并后的簿仍然按 start 升序排列且两两不相交。
实现 solution(levels: list[list[int]], new_level: list[int]) -> list[list[int]]。闭区间语义:只要 a.end >= b.start 就合并(所以 [1, 5] 和 [5, 9] 塌缩为 [1, 9])。因为 levels 已经排好序且不相交,所做的工作就是一次线性扫描——O(N) 时间、O(N) 输出、不需要二次排序。算法形状是三段:把严格在 new_level 之前的档位原样复制,把与之相切/相交的连续段折叠成一个合并区间,再把严格之后的档位原样复制。
举例:solution([[1, 3], [6, 9]], [2, 5]) 返回 [[1, 5], [6, 9]]。新区间 [2, 5] 与 [1, 3] 相交(合并为 [1, 5]),然后严格位于 [6, 9] 之前,后者原样保留。
实践背景
把新到达的价格档位区间插入到一个按 start 升序、两两不相交的订单簿里,本质上就是教科书级别的插入区间问题(LeetCode 57)穿了一身微观结构的外衣。真实交易场所不会一行存一个 tick——做市方在一段连续 tick 段上挂同样的规模时,撮合引擎和公开深度行情都会把这一段压缩成一行 [start, end],簿的不变量就是"按 start 升序、两两不相交"。每一次下单、撤单、重定价,本质上都是一次"插入区间":定位与之相切/相交的连续段,折叠下来,再发出去。如果偷懒写成 levels + [new_level] → sort → 合并相交,每次更新 O(N log N),而且白白丢掉了调用方维护的"已排序"不变量。三段线性扫描才是低延迟订单簿的标准写法,而且它能直接推广到深度行情聚合、日历屏蔽段合并,以及任何一类"在流式插入下维护一组排序且不相交的覆盖"的问题。
约束条件
- 0 ≤ `len(levels)` ≤ 10000
- `levels` 按 `levels[i][0]` 升序排列,且两两不相交(任意两个已存在区间互不相切也不相交)
- 每个区间 `[s, e]` 满足 `0 ≤ s ≤ e ≤ 1e9`
- `new_level = [s, e]` 满足 `0 ≤ s ≤ e ≤ 1e9`
- 输出为 `list[list[int]]`,按 start 升序、两两不相交;判分采用整数严格相等、保持顺序
样例
Case 1 · statement-example: overlap with first, disjoint from second
输入: [[[1,3],[6,9]],[2,5]]
期望: [[1,5],[6,9]]
新区间 [2, 5] 与 [1, 3] 相交,合并为 [1, 5];与 [6, 9] 不相切也不相交,后者原样保留。
Case 2 · statement-example: new interval spans multiple existing levels
输入: [[[1,2],[3,5],[6,7],[8,10],[12,16]],[4,8]]
期望: [[1,2],[3,10],[12,16]]
[4, 8] 与 [3, 5]、[6, 7]、[8, 10] 三段相切或相交,折叠为 [3, 10];[1, 2] 严格在前、[12, 16] 严格在后,均原样保留。
Case 3 · statement-example: empty levels returns just the new interval
输入: [[],[5,7]]
期望: [[5,7]]
空簿子,直接返回 [[5, 7]]。
Case 4 · typical: new strictly before all existing levels
输入: [[[10,12],[14,18]],[1,5]]
期望: [[1,5],[10,12],[14,18]]
[1, 5] 与所有已有档位都不相交也不相切,直接前置插入。
Case 5 · typical: new strictly after all existing levels
输入: [[[1,3],[5,7]],[10,15]]
期望: [[1,3],[5,7],[10,15]]
[10, 15] 与所有已有档位都不相交也不相切,直接追加到末尾。
最近提交
还没有提交记录。
编码区
实现 solution(...)。本地运行当前支持 Python 可见样例;服务端提交会运行可见样例和隐藏测试。
默认展示公开样例。点击「运行样例」后会在这里显示实际输出;点击「提交评测」会进入隐藏测试。
Case 1 · statement-example: overlap with first, disjoint from second
输入: [[[1,3],[6,9]],[2,5]]
期望: [[1,5],[6,9]]
新区间 [2, 5] 与 [1, 3] 相交,合并为 [1, 5];与 [6, 9] 不相切也不相交,后者原样保留。
Case 2 · statement-example: new interval spans multiple existing levels
输入: [[[1,2],[3,5],[6,7],[8,10],[12,16]],[4,8]]
期望: [[1,2],[3,10],[12,16]]
[4, 8] 与 [3, 5]、[6, 7]、[8, 10] 三段相切或相交,折叠为 [3, 10];[1, 2] 严格在前、[12, 16] 严格在后,均原样保留。
Case 3 · statement-example: empty levels returns just the new interval
输入: [[],[5,7]]
期望: [[5,7]]
空簿子,直接返回 [[5, 7]]。
Case 4 · typical: new strictly before all existing levels
输入: [[[10,12],[14,18]],[1,5]]
期望: [[1,5],[10,12],[14,18]]
[1, 5] 与所有已有档位都不相交也不相切,直接前置插入。
Case 5 · typical: new strictly after all existing levels
输入: [[[1,3],[5,7]],[10,15]]
期望: [[1,3],[5,7],[10,15]]
[10, 15] 与所有已有档位都不相交也不相切,直接追加到末尾。