LeetCode-in-Java

1801. Number of Orders in the Backlog

Medium

You are given a 2D integer array orders, where each orders[i] = [pricei, amounti, orderTypei] denotes that amounti orders have been placed of type orderTypei at the price pricei. The orderTypei is:

Note that orders[i] represents a batch of amounti independent orders with the same price and order type. All orders represented by orders[i] will be placed before all orders represented by orders[i+1] for all valid i.

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:

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.

Example 1:

Input: orders = [[10,5,0],[15,2,1],[25,1,1],[30,4,0]]

Output: 6

Explanation: Here is what happens with the orders:

Example 2:

Input: orders = [[7,1000000000,1],[15,3,0],[5,999999995,0],[5,1,1]]

Output: 999999984

Explanation: Here is what happens with the orders:

Constraints:

Solution

import java.util.Comparator;
import java.util.PriorityQueue;

public class Solution {
    private static class Order {
        int price;
        int qty;

        Order(int price, int qty) {
            this.price = price;
            this.qty = qty;
        }
    }

    public int getNumberOfBacklogOrders(int[][] orders) {
        PriorityQueue<Order> sell = new PriorityQueue<>(Comparator.comparingInt(a -> a.price));
        PriorityQueue<Order> buy = new PriorityQueue<>((a, b) -> b.price - a.price);
        for (int[] order : orders) {
            int price = order[0];
            int amount = order[1];
            int type = order[2];
            if (type == 0) {
                while (!sell.isEmpty() && sell.peek().price <= price && amount > 0) {
                    Order ord = sell.peek();
                    int toRemove = Math.min(amount, ord.qty);
                    ord.qty -= toRemove;
                    amount -= toRemove;
                    if (ord.qty == 0) {
                        sell.poll();
                    }
                }
                if (amount > 0) {
                    buy.add(new Order(price, amount));
                }
            } else {
                while (!buy.isEmpty() && buy.peek().price >= price && amount > 0) {
                    Order ord = buy.peek();
                    int toRemove = Math.min(amount, ord.qty);
                    ord.qty -= toRemove;
                    amount -= toRemove;
                    if (ord.qty == 0) {
                        buy.poll();
                    }
                }
                if (amount > 0) {
                    sell.add(new Order(price, amount));
                }
            }
        }
        long sellCount = 0;
        for (Order ord : sell) {
            sellCount += ord.qty;
        }
        long buyCount = 0;
        for (Order ord : buy) {
            buyCount += ord.qty;
        }
        long total = sellCount + buyCount;
        return (int) (total % 1000000007L);
    }
}