LeetCode in Kotlin

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.PriorityQueue

class Solution {
    private class Order(var price: Int, var qty: Int)

    fun getNumberOfBacklogOrders(orders: Array<IntArray>): Int {
        val sell = PriorityQueue(
            compareBy { a: Order -> a.price }
        )
        val buy = PriorityQueue { a: Order, b: Order -> b.price - a.price }
        for (order in orders) {
            val price = order[0]
            var amount = order[1]
            val type = order[2]
            if (type == 0) {
                while (sell.isNotEmpty() && sell.peek().price <= price && amount > 0) {
                    val ord = sell.peek()
                    val toRemove = amount.coerceAtMost(ord.qty)
                    ord.qty -= toRemove
                    amount -= toRemove
                    if (ord.qty == 0) {
                        sell.poll()
                    }
                }
                if (amount > 0) {
                    buy.add(Order(price, amount))
                }
            } else {
                while (buy.isNotEmpty() && buy.peek().price >= price && amount > 0) {
                    val ord = buy.peek()
                    val toRemove = amount.coerceAtMost(ord.qty)
                    ord.qty -= toRemove
                    amount -= toRemove
                    if (ord.qty == 0) {
                        buy.poll()
                    }
                }
                if (amount > 0) {
                    sell.add(Order(price, amount))
                }
            }
        }
        var sellCount: Long = 0
        for (ord in sell) {
            sellCount += ord.qty.toLong()
        }
        var buyCount: Long = 0
        for (ord in buy) {
            buyCount += ord.qty.toLong()
        }
        val total = sellCount + buyCount
        return (total % 1000000007L).toInt()
    }
}