← 返回编程题库
coding-consolidated-best-bid-k-feeds中等免费版2000ms未尝试

跨 K 路场所报价流的最优买价合并流

Consolidated Best-Bid Stream Across K Venue Quote Feeds

开始编码

实现 solution(feeds: list[list[list[float]]]) -> list[list[float]]。给定 K = len(feeds) 路并行的报价流,其中 feeds[k] 是一个由二元列表 [ts, bid] 组成的列表,描述场所 k 在自己买一档上每一次的报价更新。每条 feed 内部按 ts 严格升序(同一个场所不会有两条同 ts 的更新),但跨不同场所同一个 ts 是允许的。一行 [ts, bid] 读作"场所 k 在时刻 ts 把买价更新为 bid"。

按时间向前遍历每一个有任意 feed 更新的唯一全局 ts,并对每一个这样的 ts 输出一行合并后的快照:

[int_ts, float_best_bid, int_best_venue]

best_bid 是把这个 ts 上的所有更新都应用之后,每个场所最近一次报价中的最大值;尚未发出任何更新的场所不参与(其"最近一次报价"视作未设置,不是 0、也不是 -inf 真的去比)。best_bid 相等时取场所下标最小的。

feeds = [
  [[1, 100.5], [4, 100.7]],
  [[2, 100.6], [3, 100.4]],
  [[3, 100.55]],
]

逐个走过唯一的全局时刻 {1, 2, 3, 4}:

  • ts=1:仅场所 0 已发出(报价 100.5);场所 1、2 尚未启动。best = 100.5,venue 0。
  • ts=2:场所 0 最近为 100.5,场所 1 刚刚把价更新为 100.6,场所 2 尚未启动。best = 100.6,venue 1。
  • ts=3:场所 0 最近 100.5,场所 1 刚把价下调到 100.4,场所 2 刚刚发出 100.55。best = 100.55,venue 2。
  • ts=4:场所 0 刚更新为 100.7,场所 1 最近 100.4,场所 2 最近 100.55。best = 100.7,venue 0。

solution(feeds) 返回:

[[1, 100.5, 0],
 [2, 100.6, 1],
 [3, 100.55, 2],
 [4, 100.7, 0]]

需要明确的细节:当若干 feeds 共享同一个 ts(例如场所 0 和 1 都在 ts=5 各发一次),要先把这两个更新都写入"最近一次报价"表,再计算这一刻的快照——规范规定每一个唯一 ts 恰好对应一行输出,绝不是一个场所一行。feeds == [](K = 0)不在合法输入范围内(K >= 1),但 feeds[k] == [] 是允许的;如果所有 feed 都为空则返回 []K=1 时输出就是这条单 feed 自身的事件,每行的 best_venue 都是 0。

朴素地"对每一个 ts 都从头扫所有事件"是 O(N * K * 平均 ts) 的,会超时。正确的形态是用大小为 O(K) 的最小堆做 K 路归并、堆顶以 (ts, venue_idx, item_idx) 为键,每次把堆顶等于当前 ts 的条目一次性全部出堆再算快照——总体复杂度 O(N log K)。

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

实践背景

合并后的最优买价流是任何跨场所微结构分析的基石。每个交易场所在自己的时钟上发出自己的买一档报价流,因此在桌台问"现在合并后整条 tape 上的最优买价是多少?"——这是滑点归因、智能路由决策、基准构建的输入——之前必须先把 K 路并行 feed 合并为一条按时序排列的流,并同步维护每个场所的"最近一次报价"。生产中常见的两类实现陷阱:每个 heap-pop 各发一行(同一个 wire 时刻发生的更新会被重复上报)、以及把尚未发出任何更新的场所也算进 max——两者都会悄悄污染下游每一个吃这条合并流的指标。

约束条件

  • 1 <= K <= 50,其中 K = len(feeds)。所有 feeds 总事件数 0 <= sum(len(feeds[k])) <= 5000。
  • 每条事件是一个二元列表 [ts, bid],0 <= ts <= 1e9(整数),0.001 <= bid <= 1e6(正浮点数)。
  • 在同一个 feed 内,ts 严格升序——同一个场所不会有两条同 ts 的更新;跨不同 feed 同一个 ts 是允许的。
  • 输出是 list[list],每行 [int_ts, float_best_bid, int_best_venue],按 ts 严格升序排列。每个有任意 feed 更新的唯一 ts 恰好对应**一行**输出。
  • 每个发出的 ts 上,best_bid 是所有"已有报价的场所"的最近一次报价中的最大值;尚未发出任何更新的场所不参与 max。最大值打平时取场所下标最小的。
  • 如果 feeds 非空但所有 feeds[k] 都为空,返回 []。

样例

Case 1 · statement-example: 3 venues, 4 unique ts

输入: [[[[1,100.5],[4,100.7]],[[2,100.6],[3,100.4]],[[3,100.55]]]]

期望: [[1,100.5,0],[2,100.6,1],[3,100.55,2],[4,100.7,0]]

正文示例:t=1 仅场所 0 启动 (100.5,0);t=2 场所 1 100.6 胜出;t=3 场所 1 降到 100.4,场所 2 刚刚 100.55 胜出;t=4 场所 0 更新到 100.7 胜出。

Case 2 · visible: tied ts at t=1, venue 1 wins on value

输入: [[[[1,50],[3,60]],[[1,55],[3,60]]]]

期望: [[1,55,1],[3,60,0]]

t=1 两路同时更新:50.0 vs 55.0 -> 55.0 胜出 venue 1;t=3 两路皆 60.0,tiebreak 取 venue 0。

Case 3 · visible: K=1 single feed, venue always 0

输入: [[[[5,99],[10,101],[11,100.5]]]]

期望: [[5,99,0],[10,101,0],[11,100.5,0]]

K=1 时每行的 best_venue 恒为 0;输出就是该 feed 自身的更新序列。

最近提交

还没有提交记录。

编码区

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

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

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

Case 1 · statement-example: 3 venues, 4 unique ts

输入: [[[[1,100.5],[4,100.7]],[[2,100.6],[3,100.4]],[[3,100.55]]]]

期望: [[1,100.5,0],[2,100.6,1],[3,100.55,2],[4,100.7,0]]

正文示例:t=1 仅场所 0 启动 (100.5,0);t=2 场所 1 100.6 胜出;t=3 场所 1 降到 100.4,场所 2 刚刚 100.55 胜出;t=4 场所 0 更新到 100.7 胜出。

Case 2 · visible: tied ts at t=1, venue 1 wins on value

输入: [[[[1,50],[3,60]],[[1,55],[3,60]]]]

期望: [[1,55,1],[3,60,0]]

t=1 两路同时更新:50.0 vs 55.0 -> 55.0 胜出 venue 1;t=3 两路皆 60.0,tiebreak 取 venue 0。

Case 3 · visible: K=1 single feed, venue always 0

输入: [[[[5,99],[10,101],[11,100.5]]]]

期望: [[5,99,0],[10,101,0],[11,100.5,0]]

K=1 时每行的 best_venue 恒为 0;输出就是该 feed 自身的更新序列。