← 返回编程题库
coding-order-queue-priority中等免费版2000ms未尝试

撮合队列优先级排序(买卖两侧分别排队)

Order Queue Priority

开始编码

撮合引擎每次撮合前,都要把当下所有挂单按各自侧的优先级排成一条队列:买盘里愿意出更高价的客户先成交,卖盘里愿意接受更低价的客户先成交,价格打平时先挂出的优先(FIFO)。这就是经典的 price-time priority 队列规则——每一家正经的限价订单簿都长这样。

请实现 solution(orders: list[dict]) -> dict:把输入里所有订单按 side 分流到两条队列,每条队列按本侧的 price-time priority 排好,然后整体打包返回。每条 orders[i] 至少可能带 order_id (str)、side (str)、price (float)、time (int),也可能带 qty 等额外字段。处理口径如下:

  1. 过滤side 必须严格等于字面量 "buy""sell"(小写、不做 lower(),不接受 "BUY" / "b" / None);price 必须存在、非 None 且 > 0time 必须存在且非 None;order_id 必须存在、非 None 且 strip() 后非空。任一不满足则整条订单丢弃。原始 dict 不修改、不剥空白、不重新构造——直接进结果。
  2. 排序
  • **买盘 (side == "buy")**:先按 price 降序——出价高者先排队;价相等按 time 升序——先挂的优先;仍相等按 order_id 字典序升序——保证相同输入返回顺序确定。
  • **卖盘 (side == "sell")**:先按 price 升序——要价低者先排队;价相等按 time 升序;仍相等按 order_id 字典序升序
  1. 打包。返回 {"buys": [<order>, ...], "sells": [<order>, ...]},每个 <order> 是输入里那条原始 dict 引用(含 qty 等所有额外字段)。

举例:solution([{"order_id": "A", "side": "buy", "price": 100.5, "time": 1000, "qty": 10}, {"order_id": "B", "side": "buy", "price": 100.5, "time": 999, "qty": 5}, {"order_id": "C", "side": "sell", "price": 101.0, "time": 1001, "qty": 8}, {"order_id": "D", "side": "sell", "price": 100.8, "time": 1005, "qty": 12}]) 应返回 {"buys": [{"order_id": "B", ...}, {"order_id": "A", ...}], "sells": [{"order_id": "D", ...}, {"order_id": "C", ...}]}。买盘里 A 与 B 同价 100.5,B 的 time=999 早于 A 的 time=1000,按 FIFO 先排队;卖盘里 D 的 price=100.8 比 C 的 101.0 低,D 先排队(卖盘出价低者优先)。注意 D 的 time=1005 反而比 C 的 1001 晚——price-time priority 是先看价再看时间,时间不会越过价格。

10000 条订单的体量下,请用 O(N log N) 的方案:一次过滤、两次 sorted 各扫一侧,复杂度对应交易所每个 tick 重排队列的开销就足够了。

约束条件

  • 0 ≤ len(orders) ≤ 10000
  • 每条订单是 dict,至少可能带 `order_id` (str)、`side` (str)、`price` (float|int)、`time` (int),也可能带 `qty` 等额外字段
  • `side` 仅接受字面量小写 `"buy"` 或 `"sell"`;其余值(None、`"BUY"`、`"b"` 等)整条丢弃
  • `price` 必须存在、非 None 且 `> 0`;否则整条丢弃
  • `time` 必须存在且非 None;否则整条丢弃。允许两条订单 `time` 相等
  • `order_id` 必须存在、非 None 且 `str.strip()` 后非空;否则整条丢弃。`order_id` 不做 strip,原样保留进结果
  • 返回 `{"buys": list[dict], "sells": list[dict]}`;每个 dict 是输入里那条原始订单(保留所有字段)
  • 买盘排序:`price` **降序**;价相等按 `time` **升序**;仍相等按 `order_id` **升序**(字典序)
  • 卖盘排序:`price` **升序**;价相等按 `time` **升序**;仍相等按 `order_id` **升序**(字典序)

样例

Case 1 · example from statement (price-time priority on both sides)

输入: [[{"order_id":"A","side":"buy","price":100.5,"time":1000,"qty":10},{"order_id":"B","side":"buy","price":100.5,"time":999,"qty":5},{"order_id":"C","side":"sell","price":101,"time":1001,"qty":8},{"order_id":"D","side":"sell","price":100.8,"time":1005,"qty":12}]]

期望: {"buys":[{"order_id":"B","side":"buy","price":100.5,"time":999,"qty":5},{"order_id":"A","side":"buy","price":100.5,"time":1000,"qty":10}],"sells":[{"order_id":"D","side":"sell","price":100.8,"time":1005,"qty":12},{"order_id":"C","side":"sell","price":101,"time":1001,"qty":8}]}

买盘 A、B 同价 100.5,B 的 time=999 早于 A 的 time=1000,B 先排队。卖盘 D 的 price=100.8 比 C 的 101.0 低,D 先排队——卖盘出价低者优先;注意 D 的 time=1005 实际比 C 的 1001 晚,time 不会越过 price。

Case 2 · multiple price levels and FIFO at same level

输入: [[{"order_id":"B1","side":"buy","price":99,"time":100},{"order_id":"B2","side":"buy","price":100,"time":200},{"order_id":"B3","side":"buy","price":100,"time":150},{"order_id":"B4","side":"buy","price":101,"time":250},{"order_id":"S1","side":"sell","price":102,"time":110},{"order_id":"S2","side":"sell","price":103,"time":120},{"order_id":"S3","side":"sell","price":102,"time":130}]]

期望: {"buys":[{"order_id":"B4","side":"buy","price":101,"time":250},{"order_id":"B3","side":"buy","price":100,"time":150},{"order_id":"B2","side":"buy","price":100,"time":200},{"order_id":"B1","side":"buy","price":99,"time":100}],"sells":[{"order_id":"S1","side":"sell","price":102,"time":110},{"order_id":"S3","side":"sell","price":102,"time":130},{"order_id":"S2","side":"sell","price":103,"time":120}]}

买盘按 price 降序:B4 (101) > B2/B3 (100) > B1 (99);100 这一档里 B3 的 time=150 早于 B2 的 time=200,B3 排在 B2 前面。卖盘按 price 升序:S1/S3 (102) < S2 (103);102 这一档里 S1 的 time=110 早于 S3 的 time=130。

最近提交

还没有提交记录。

编码区

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

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

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

Case 1 · example from statement (price-time priority on both sides)

输入: [[{"order_id":"A","side":"buy","price":100.5,"time":1000,"qty":10},{"order_id":"B","side":"buy","price":100.5,"time":999,"qty":5},{"order_id":"C","side":"sell","price":101,"time":1001,"qty":8},{"order_id":"D","side":"sell","price":100.8,"time":1005,"qty":12}]]

期望: {"buys":[{"order_id":"B","side":"buy","price":100.5,"time":999,"qty":5},{"order_id":"A","side":"buy","price":100.5,"time":1000,"qty":10}],"sells":[{"order_id":"D","side":"sell","price":100.8,"time":1005,"qty":12},{"order_id":"C","side":"sell","price":101,"time":1001,"qty":8}]}

买盘 A、B 同价 100.5,B 的 time=999 早于 A 的 time=1000,B 先排队。卖盘 D 的 price=100.8 比 C 的 101.0 低,D 先排队——卖盘出价低者优先;注意 D 的 time=1005 实际比 C 的 1001 晚,time 不会越过 price。

Case 2 · multiple price levels and FIFO at same level

输入: [[{"order_id":"B1","side":"buy","price":99,"time":100},{"order_id":"B2","side":"buy","price":100,"time":200},{"order_id":"B3","side":"buy","price":100,"time":150},{"order_id":"B4","side":"buy","price":101,"time":250},{"order_id":"S1","side":"sell","price":102,"time":110},{"order_id":"S2","side":"sell","price":103,"time":120},{"order_id":"S3","side":"sell","price":102,"time":130}]]

期望: {"buys":[{"order_id":"B4","side":"buy","price":101,"time":250},{"order_id":"B3","side":"buy","price":100,"time":150},{"order_id":"B2","side":"buy","price":100,"time":200},{"order_id":"B1","side":"buy","price":99,"time":100}],"sells":[{"order_id":"S1","side":"sell","price":102,"time":110},{"order_id":"S3","side":"sell","price":102,"time":130},{"order_id":"S2","side":"sell","price":103,"time":120}]}

买盘按 price 降序:B4 (101) > B2/B3 (100) > B1 (99);100 这一档里 B3 的 time=150 早于 B2 的 time=200,B3 排在 B2 前面。卖盘按 price 升序:S1/S3 (102) < S2 (103);102 这一档里 S1 的 time=110 早于 S3 的 time=130。