← 返回编程题库
coding-insert-and-merge-orderbook-levels中等免费版2000ms未尝试

插入并合并订单簿价格档位区间

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 可见样例;服务端提交会运行可见样例和隐藏测试。

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

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

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] 与所有已有档位都不相交也不相切,直接追加到末尾。