|
| 1 | +// Source : https://leetcode.com/problems/number-of-orders-in-the-backlog/ |
| 2 | +// Author : Hao Chen |
| 3 | +// Date : 2021-03-21 |
| 4 | + |
| 5 | +/***************************************************************************************************** |
| 6 | + * |
| 7 | + * You are given a 2D integer array orders, where each orders[i] = [pricei, amounti, orderTypei] |
| 8 | + * denotes that amounti orders have been placed of type orderTypei at the price pricei. The orderTypei |
| 9 | + * is: |
| 10 | + * |
| 11 | + * 0 if it is a batch of buy orders, or |
| 12 | + * 1 if it is a batch of sell orders. |
| 13 | + * |
| 14 | + * Note that orders[i] represents a batch of amounti independent orders with the same price and order |
| 15 | + * type. All orders represented by orders[i] will be placed before all orders represented by |
| 16 | + * orders[i+1] for all valid i. |
| 17 | + * |
| 18 | + * There is a backlog that consists of orders that have not been executed. The backlog is initially |
| 19 | + * empty. When an order is placed, the following happens: |
| 20 | + * |
| 21 | + * If the order is a buy order, you look at the sell order with the smallest price in the |
| 22 | + * backlog. If that sell order's price is smaller than or equal to the current buy order's price, they |
| 23 | + * will match and be executed, and that sell order will be removed from the backlog. Else, the buy |
| 24 | + * order is added to the backlog. |
| 25 | + * Vice versa, if the order is a sell order, you look at the buy order with the largest price |
| 26 | + * in the backlog. If that buy order's price is larger than or equal to the current sell order's |
| 27 | + * price, they will match and be executed, and that buy order will be removed from the backlog. Else, |
| 28 | + * the sell order is added to the backlog. |
| 29 | + * |
| 30 | + * Return the total amount of orders in the backlog after placing all the orders from the input. Since |
| 31 | + * this number can be large, return it modulo 109 + 7. |
| 32 | + * |
| 33 | + * Example 1: |
| 34 | + * |
| 35 | + * Input: orders = [[10,5,0],[15,2,1],[25,1,1],[30,4,0]] |
| 36 | + * Output: 6 |
| 37 | + * Explanation: Here is what happens with the orders: |
| 38 | + * - 5 orders of type buy with price 10 are placed. There are no sell orders, so the 5 orders are |
| 39 | + * added to the backlog. |
| 40 | + * - 2 orders of type sell with price 15 are placed. There are no buy orders with prices larger than |
| 41 | + * or equal to 15, so the 2 orders are added to the backlog. |
| 42 | + * - 1 order of type sell with price 25 is placed. There are no buy orders with prices larger than or |
| 43 | + * equal to 25 in the backlog, so this order is added to the backlog. |
| 44 | + * - 4 orders of type buy with price 30 are placed. The first 2 orders are matched with the 2 sell |
| 45 | + * orders of the least price, which is 15 and these 2 sell orders are removed from the backlog. The |
| 46 | + * 3rd order is matched with the sell order of the least price, which is 25 and this sell order is |
| 47 | + * removed from the backlog. Then, there are no more sell orders in the backlog, so the 4th order is |
| 48 | + * added to the backlog. |
| 49 | + * Finally, the backlog has 5 buy orders with price 10, and 1 buy order with price 30. So the total |
| 50 | + * number of orders in the backlog is 6. |
| 51 | + * |
| 52 | + * Example 2: |
| 53 | + * |
| 54 | + * Input: orders = [[7,1000000000,1],[15,3,0],[5,999999995,0],[5,1,1]] |
| 55 | + * Output: 999999984 |
| 56 | + * Explanation: Here is what happens with the orders: |
| 57 | + * - 109 orders of type sell with price 7 are placed. There are no buy orders, so the 109 orders are |
| 58 | + * added to the backlog. |
| 59 | + * - 3 orders of type buy with price 15 are placed. They are matched with the 3 sell orders with the |
| 60 | + * least price which is 7, and those 3 sell orders are removed from the backlog. |
| 61 | + * - 999999995 orders of type buy with price 5 are placed. The least price of a sell order is 7, so |
| 62 | + * the 999999995 orders are added to the backlog. |
| 63 | + * - 1 order of type sell with price 5 is placed. It is matched with the buy order of the highest |
| 64 | + * price, which is 5, and that buy order is removed from the backlog. |
| 65 | + * Finally, the backlog has (1000000000-3) sell orders with price 7, and (999999995-1) buy orders with |
| 66 | + * price 5. So the total number of orders = 1999999991, which is equal to 999999984 % (109 + 7). |
| 67 | + * |
| 68 | + * Constraints: |
| 69 | + * |
| 70 | + * 1 <= orders.length <= 105 |
| 71 | + * orders[i].length == 3 |
| 72 | + * 1 <= pricei, amounti <= 109 |
| 73 | + * orderTypei is either 0 or 1. |
| 74 | + ******************************************************************************************************/ |
| 75 | + |
| 76 | +class Order { |
| 77 | +public: |
| 78 | + int price; |
| 79 | + int amount; |
| 80 | +}; |
| 81 | + |
| 82 | +enum COMP { GREATER, LESS }; |
| 83 | + |
| 84 | +template <COMP op> |
| 85 | +class OrderComp { |
| 86 | +public: |
| 87 | + bool operator() (const Order& lhs, const Order& rhs) { |
| 88 | + if (op == GREATER) { |
| 89 | + return lhs.price > rhs.price; |
| 90 | + } |
| 91 | + return lhs.price < rhs.price; |
| 92 | + } |
| 93 | +}; |
| 94 | + |
| 95 | + |
| 96 | +class Solution { |
| 97 | +private: |
| 98 | + template<typename T1, typename T2> |
| 99 | + void processOrder(T1& q1, T2& q2, COMP op, int price, int amount, string n1="q1", string n2="q2") { |
| 100 | + if (q2.size() == 0) { |
| 101 | + q1.push(Order{price, amount}); |
| 102 | + return; |
| 103 | + } |
| 104 | + |
| 105 | + while(!q2.empty() && amount > 0 ){ |
| 106 | + Order order = q2.top(); |
| 107 | + if (op == GREATER && order.price > price ) break; |
| 108 | + if (op == LESS && order.price < price) break; |
| 109 | + |
| 110 | + q2.pop(); |
| 111 | + //cout << "=> deQueue("<< n2 << "): " << order.price << ", "<< order.amount << endl; |
| 112 | + |
| 113 | + int amt = min(order.amount, amount); |
| 114 | + order.amount -= amt; |
| 115 | + amount -= amt; |
| 116 | + if (order.amount > 0) { |
| 117 | + //cout << "<= enQueue("<< n2 <<"): " << order.price << ", "<< order.amount << endl; |
| 118 | + q2.push(order); |
| 119 | + } |
| 120 | + } |
| 121 | + if (amount > 0) { |
| 122 | + //cout << "<= enQueue("<< n1 <<"): " << price << ", "<< amount << endl; |
| 123 | + q1.push(Order{price, amount}); |
| 124 | + } |
| 125 | + } |
| 126 | + |
| 127 | + template<typename T> |
| 128 | + void countQ(T& q, int& amount){ |
| 129 | + while(!q.empty()) { |
| 130 | + amount = (amount + q.top().amount) % 1000000007; |
| 131 | + q.pop(); |
| 132 | + } |
| 133 | + } |
| 134 | +public: |
| 135 | + int getNumberOfBacklogOrders(vector<vector<int>>& orders) { |
| 136 | + |
| 137 | + priority_queue<Order, vector<Order>, OrderComp<GREATER>> sell; |
| 138 | + priority_queue<Order, vector<Order>, OrderComp<LESS>> buy; |
| 139 | + |
| 140 | + |
| 141 | + for (auto& order : orders) { |
| 142 | + int& price = order[0]; |
| 143 | + int& amount = order[1]; |
| 144 | + |
| 145 | + if (order[2] == 0) { //buy order |
| 146 | + processOrder(buy, sell, GREATER, price, amount, "buy", "sell"); |
| 147 | + }else { // sell order |
| 148 | + processOrder(sell, buy, LESS, price, amount, "sell", "buy"); |
| 149 | + } |
| 150 | + } |
| 151 | + |
| 152 | + int amount = 0; |
| 153 | + countQ(sell, amount); |
| 154 | + countQ(buy, amount); |
| 155 | + return amount ; |
| 156 | + } |
| 157 | +}; |
0 commit comments