这道题在于题目的理解。这里有两种未执行的积压订单,销售订单sell 和 采购订单buy。提交订单时,如果当前订单:
- 是采购订单,去积压的销售订单中查找价格最低的
- 是销售订单,需要去积压的采购订单中去查找价格最高的
从价格最低和最高可以确定这里可以使用堆排序。需要去销售积压订单中查找最小值,用小顶堆;需要在采购积压订单中查找最大值,用大顶堆。
具体思路:
- 判断是何种订单
- 采购订单
- 是否有积压销售订单
- 没有:将采购订单加入积压采购订单
- 有:比较采购价格是否大于销售积压订单中的最小值,
- 积压订单数量与当前采购订单的数量关系
- 积压销售订单大于采购订单: 清空采购订单,减小积压销售订单数量
- 积压销售订单等于采购订单:清空采购订单和积压销售订单
- 积压销售订单小于采购订单:清空当前价格的积压销售订单,减小采购订单;寻找下一个最小价格的积压销售订单;继续比较数量。。。
- 积压订单数量与当前采购订单的数量关系
- 是否有积压销售订单
- 销售订单
- 是否有积压的采购订单
-
没有
-
有 。。。(这里的比较和上述相似,只是这里是取最大值)
-
- 是否有积压的采购订单
- 采购订单
代码:
大小堆的实现可以参考专栏的前几篇文章,因为要实现最大和最小堆,如果把代码也贴过来,代码的就太长了。
// 大顶堆 MaxBinaryHeap
// 小顶堆 MinBinaryHeap
const getNumberOfBacklogOrders = function (orders) {
// 大顶堆 积压的采购订单
const buyBlocks = new MaxBinaryHeap()
// 小顶堆 积压的销售订单
const sellBlocks = new MinBinaryHeap()
for (let i = 0; i < orders.length; i++) {
const order = orders[i]
if (order[2] === 0) {
// 当前为采购订单,但是没有积压销售订单,直接将采购订单加入积压
if (sellBlocks.length === 0) {
buyBlocks.insert(order)
} else {
// 找到积压的销售订单比当前采购订单 价格 低的积压订单
// 从最小值开始
if (sellBlocks.top[0] <= order[0]) {
while (sellBlocks.length && order[1] > 0 && sellBlocks.top[0] <= order[0]) {
let minSell = sellBlocks.pop()
let diff = minSell[1] - order[1]
if (diff < 0) {
// 当前订单还需要采购,继续在积压销售订单中查找
order[1] = -diff
} else if (diff >= 0) {
// 清空
minSell[1] = diff
order[1] = 0
sellBlocks.insert(minSell)
}
}
}
// 如果当前订单没有被清空,加入积压订单
if (order[1] !== 0) {
buyBlocks.insert(order)
}
}
} else {
if (buyBlocks.length === 0) {
sellBlocks.insert(order)
} else {
// 找到积压的采购订单比当前销售订单 价格 高的积压订单
// 从最大值开始
if (buyBlocks.top[0] >= order[0]) {
while(buyBlocks.length && order[1] > 0 && buyBlocks.top[0] >= order[0]) {
const maxBuy = buyBlocks.pop()
let diff = maxBuy[1] - order[1]
if (diff < 0) {
order[1] = -diff
} else if (diff >= 0) {
maxBuy[1] = diff
order[1] = 0
buyBlocks.insert(maxBuy)
}
}
}
if (order[1] !== 0) {
sellBlocks.insert(order)
}
}
}
}
let size = 0
while (sellBlocks.length) {
const v = sellBlocks.pop()
size += v[1]
}
while (buyBlocks.length) {
const v = buyBlocks.pop()
size += v[1]
}
return size % (Math.pow(10, 9) + 7)
}