1801. 积压订单中的订单总数
大、小堆 - 模拟
写的有点小复杂,大佬勿喷。只是记录一下自己的做题思路。
思路:
- 使用“小根堆 -->
sellQueue
积压队列”、“大根堆 -->buyQueue
积压队列”; - “采购”订单:
- “没人卖”、或“因为本次采购手里钱不够,而买不起”时,则直接将当前采购订单积压到
buyQueue
,即可; - 本次采购能买得起时,则持续“采购”,直至(对应
while
)“钱不足”、或“本次订单需求完事儿了” 、或 “已经没有商品可以采购了”;(while
的 3 个循环条件)- 采购订单数较少时,则将销售订单减去采购订单数后,重新入
sellQueue
,并结束本轮“采购”;–>amount = 0;
- 采购订单较多时,本次购买后,继续“尝试”购买. -->
amount -= top.amount;
- 采购订单数较少时,则将销售订单减去采购订单数后,重新入
- 若“持续采购”结束后,本次还剩余没有采购的订单,则加入积压到
buyQueue
- “没人卖”、或“因为本次采购手里钱不够,而买不起”时,则直接将当前采购订单积压到
- “销售”订单:
逻辑同上“采购订单”中…
class Order {
int amount;
int price;
public Order(int amount, int price) {
this.amount = amount;
this.price = price;
}
@Override
public String toString() {
return "Order{" +
"amount=" + amount +
", price=" + price +
'}';
}
}
class Solution {
public int getNumberOfBacklogOrders(int[][] orders) {
// 小根堆 --> sell 积压
Queue<Order> sellQueue = new PriorityQueue<>((order1, order2) -> {
return order1.price - order2.price;
});
// 大根堆 --> buy 积压
Queue<Order> buyQueue = new PriorityQueue<>((order1, order2) -> {
return order2.price - order1.price;
});
int res = 0;
final int MOD = (int) (1e9 + 7);
for (int i = 0; i < orders.length; i++) {
int price = orders[i][0];
int amount = orders[i][1];
int type = orders[i][2];
if (type == 0) { // buy
// “没人卖”或“手里钱不够,买不起”时,则直接将当前采购订单积压到buyQueue,即可
if (sellQueue.isEmpty() || price < sellQueue.peek().price) {
buyQueue.offer(new Order(amount, price));
continue;
}
// 能买得起
while (!sellQueue.isEmpty() && price >= sellQueue.peek().price && amount > 0) {
Order top = sellQueue.poll();
// 采购订单数较少时,则将销售订单减去采购订单数后,重新入sellQueue
if (amount < top.amount) {
top.amount -= amount;
amount = 0; // 本次采购需求 全部解决
sellQueue.offer(top);
} else { // 采购订单较多时,本次购买后,继续尝试购买
amount -= top.amount;
}
}
// 本次还剩余没有采购的订单,则加入积压到buyQueue
if (amount > 0) {
buyQueue.offer(new Order(amount, price));
}
} else { // sell
// “没人买”或“卖的价格太贵,卖不掉”时,则直接将当前销售订单积压到sellQueue,即可
if (buyQueue.isEmpty() || price > buyQueue.peek().price) {
sellQueue.offer(new Order(amount, price));
continue;
}
//
while (!buyQueue.isEmpty() && price <= buyQueue.peek().price && amount > 0) {
Order top = buyQueue.poll();
// 销售订单数较少时,则采购订单减去销售订单数后,重新入buyQueue
if (amount < top.amount) {
top.amount -= amount;
amount = 0; // 本次销售需求 全部解决
buyQueue.offer(top);
} else { // 销售订单较多时,本次销售后,继续尝试销售
amount -= top.amount;
}
}
// 本次还剩余没有销售的订单,则加入积压到sellQueue
if (amount > 0) {
sellQueue.offer(new Order(amount, price));
}
}
}
// 统计两个队列中所有订单号
for (Order order : sellQueue) {
res = (res + order.amount) % MOD;
}
for (Order order : buyQueue) {
res = (res + order.amount) % MOD;
}
return res;
}
public static void main(String[] args) {
// int[][] orders = {{10,5,0},{15,2,1},{25,1,1},{30,4,0}};
int[][] orders = {{7,1000000000,1},{15,3,0},{5,999999995,0},{5,1,1}};
System.out.println(new Solution().getNumberOfBacklogOrders(orders));
}
}