我们在进行订单撮合系统的构建时,可能会遇到如下问题:
给定一个二维整数数组 orders
,其中每个 orders[i] = [pricei, amounti, orderTypei]
表示有 amounti
笔订单,类型为 orderTypei
,价格为 pricei
:
orderTypei == 0
表示这是一个 采购订单(Buy)orderTypei == 1
表示这是一个 销售订单(Sell)每条订单在输入中按时间顺序排列,即先于 orders[i+1]
。
订单匹配规则如下:
订单一旦匹配,会消耗对应数量的订单;多余的部分会继续参与撮合或被放入积压订单中。
要求: 所有订单处理完成后,返回积压订单的总数量(对 10 9 + 7 10^9 + 7 109+7 取模)。
该问题实质上是一个订单撮合系统模拟问题,要求我们实现一个小型交易所的核心撮合逻辑。
buy_heap
: 最大堆,按 -price
存储(Python 的 heapq
是最小堆,所以取反)。sell_heap
: 最小堆,按正常 price
存储。以下是完整的 Python 实现:
import heapq
from typing import List
class Solution:
def getNumberOfBacklogOrders(self, orders: List[List[int]]) -> int:
MOD = 10**9 + 7
buy_heap = [] # 最大堆(按负 price 存储)
sell_heap = [] # 最小堆(正常 price 存储)
for price, amount, orderType in orders:
if orderType == 0: # buy order
# 匹配最低价 sell
while amount > 0 and sell_heap and sell_heap[0][0] <= price:
sell_price, sell_amount = heapq.heappop(sell_heap)
if sell_amount > amount:
heapq.heappush(sell_heap, (sell_price, sell_amount - amount))
amount = 0
else:
amount -= sell_amount
if amount > 0:
heapq.heappush(buy_heap, (-price, amount))
else: # sell order
# 匹配最高价 buy
while amount > 0 and buy_heap and -buy_heap[0][0] >= price:
buy_price, buy_amount = heapq.heappop(buy_heap)
if buy_amount > amount:
heapq.heappush(buy_heap, (buy_price, buy_amount - amount))
amount = 0
else:
amount -= buy_amount
if amount > 0:
heapq.heappush(sell_heap, (price, amount))
# 统计剩余积压订单
total = sum(amount for _, amount in buy_heap + sell_heap)
return total % MOD
heappush
和 heappop
一次,复杂度为 O(n log n)
,其中 n
为订单数量。n
条积压订单在两个堆中,复杂度为 O(n)
。输入:
orders = [
[10, 5, 0], # buy 5 @10
[15, 2, 1], # sell 2 @15
[25, 1, 1], # sell 1 @25
[30, 4, 0] # buy 4 @30
]
buy_heap=[(-10,5)]
sell_heap=[(15,2)]
sell_heap=[(15,2),(25,1)]
buy_heap=[(-10,5),(-30,1)]
积压订单总数:5 + 1 = 6
输出:6
# 所有订单完全匹配,无积压
orders = [
[10, 2, 0],
[5, 2, 1]
]
# 输出: 0
# 多次交替撮合
orders = [
[7, 5, 0],
[9, 1, 1],
[5, 2, 1],
[6, 1, 1],
[7, 1, 1],
[10, 2, 0]
]
# 输出: (手动模拟或代码验证)
方法 | 时间复杂度 | 空间复杂度 | 优点 | 缺点 |
---|---|---|---|---|
堆(优先队列) | O(n log n) | O(n) | 高效模拟匹配过程 | 实现较繁琐,需要注意堆结构细节 |
简单列表模拟 | O(n²) | O(n) | 结构直观 | 匹配效率低,超时风险高 |
因此,使用 最小堆+最大堆 是处理此类问题的最优解法。
SortedDict
) 提高局部修改效率(Python 可用 sortedcontainers
)。这道题本质是一个「堆模拟优先匹配」的问题,考察:
通过本题可以深刻理解堆的实用价值,并掌握一个交易撮合系统的雏形。