积压订单中的订单总数【LC1801】
You are given a 2D integer array
orders
, where eachorders[i] = [pricei, amounti, orderTypei]
denotes thatamounti
orders have been placed of typeorderTypei
at the pricepricei
. TheorderTypei
is:
0
if it is a batch ofbuy
orders, or1
if it is a batch ofsell
orders.Note that
orders[i]
represents a batch ofamounti
independent orders with the same price and order type. All orders represented byorders[i]
will be placed before all orders represented byorders[i+1]
for all validi
.There is a backlog that consists of orders that have not been executed. The backlog is initially empty. When an order is placed, the following happens:
- If the order is a
buy
order, you look at thesell
order with the smallest price in the backlog. If thatsell
order’s price is smaller than or equal to the currentbuy
order’s price, they will match and be executed, and thatsell
order will be removed from the backlog. Else, thebuy
order is added to the backlog.- Vice versa, if the order is a
sell
order, you look at thebuy
order with the largest price in the backlog. If thatbuy
order’s price is larger than or equal to the currentsell
order’s price, they will match and be executed, and thatbuy
order will be removed from the backlog. Else, thesell
order is added to the backlog.Return the total amount of orders in the backlog after placing all the orders from the input. Since this number can be large, return it modulo
109 + 7
.
-
思路:使用两个优先队列存储类型为
buy
或者sell
的积压订单,根据规则删除积压订单,并统计积压订单的数量,最后返回结果即可- 当遍历到的订单是采购订单时,从优先队列
sell
中删除能够删除的所有积压订单,销售价格需小于等于采购价格,并且需要优先删除销售价格较小的订单,因此优先队列sell
以price
升序排序 - 当遍历到的订单是销售订单时,从优先队列
buy
中删除能够删除的所有积压订单,采购价格需大于等于销售价格,并且需要优先删除采购价格更大的订单,因此优先队列buy
以price
降序排序
- 当遍历到的订单是采购订单时,从优先队列
-
实现
- 使用int类型变量
count
统计积压订单的数量,遇到新订单时先将新订单数量累加至count
,每次提交订单时删除相应的数量,注意减法为了避免负数取余时需要加MOD
class Solution { public int getNumberOfBacklogOrders(int[][] orders) { int MOD = (int)(1e9 + 7); PriorityQueue<int[]> buy = new PriorityQueue<int[]>((o1, o2) -> (o2[0] - o1[0])); PriorityQueue<int[]> sell = new PriorityQueue<int[]>((o1, o2) -> (o1[0] - o2[0])); long count = 0;// 统计积压订单数量 for (int[] order : orders){ int price = order[0], amount = order[1], type = order[2]; count = (count + amount) % MOD; if (type == 0){// buy while(!sell.isEmpty() && sell.peek()[0] <= price){ int[] minSell = sell.poll(); int num = Math.min(amount, minSell[1]); minSell[1] -= num; amount -= num; // count = (count - 2 * num) % MOD; count = (count + MOD- 2 * num) % MOD;// 避免遇到负数 if (amount == 0 && minSell[1] != 0){ sell.add(new int[]{minSell[0], minSell[1]}); break; } } if (amount != 0){ buy.add(new int[]{price, amount}); } }else{// sell while(!buy.isEmpty() && buy.peek()[0] >= price){ int[] maxBuy = buy.poll(); int num = Math.min(amount, maxBuy[1]); maxBuy[1] -= num; amount -= num; // count = (count - 2 * num) % MOD; count = (count + MOD- 2 * num) % MOD; if (amount == 0 && maxBuy[1] != 0){ buy.add(new int[]{maxBuy[0], maxBuy[1]}); break; } } if (amount != 0){ sell.add(new int[]{price, amount}); } } } return (int)count; } }
- 复杂度
- 时间复杂度:O(nlogn)O(nlogn)O(nlogn),需要遍历数组
orders
一次,对于每个元素处理优先队列的时间是 O(logn)O(logn)O(logn),共需要 O(nlogn)O(nlogn)O(nlogn)的时间,遍历结束之后计算剩余的积压订单总数需要 O(nlogn)O(nlogn)O(nlogn) 的时间。 - 空间复杂度:O(n)O(n)O(n)
- 时间复杂度:O(nlogn)O(nlogn)O(nlogn),需要遍历数组
- 使用int类型变量