forked from AnasImloul/Leetcode-Solutions
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNumber of Orders in the Backlog.js
121 lines (105 loc) · 3.74 KB
/
Number of Orders in the Backlog.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
var getNumberOfBacklogOrders = function(orders) {
const buyHeap = new Heap((child, parent) => child.price > parent.price)
const sellHeap = new Heap((child, parent) => child.price < parent.price)
for (let [price, amount, orderType] of orders) {
// sell
if (orderType) {
// while there are amount to be decremented from the sell,
// orders to in the buy backlog, and the price of the largest
// price is greater than the sell price decrement the
// amount of the order with the largest price by the amount
while (amount > 0 && buyHeap.peak() && buyHeap.peak().price >= price) {
if (buyHeap.peak().amount > amount) {
buyHeap.peak().amount -= amount
amount = 0
} else {
amount -= buyHeap.pop().amount
}
}
// if there is any amount left, add it to the sale backlog
if (amount) {
sellHeap.push({ price, amount })
}
// buy
} else {
// while there are amount to be decremented from the buy,
// orders to in the sell backlog, and the price of the smallest
// price is less than the buy price decrement the
// amount of the order with the smallest price by the amount
while (amount > 0 && sellHeap.peak() && sellHeap.peak().price <= price) {
if (sellHeap.peak().amount > amount) {
sellHeap.peak().amount -= amount
amount = 0
} else {
amount -= sellHeap.pop().amount;
}
}
// if there is any amount left, add it to the buy backlog
if (amount) {
buyHeap.push({ price, amount })
}
}
}
// total all of the amounts in both backlogs and return the result
let accumultiveAmount = 0;
for (const { amount } of buyHeap.store) {
accumultiveAmount += amount;
}
for (const { amount } of sellHeap.store) {
accumultiveAmount += amount;
}
return accumultiveAmount % 1000000007
};
class Heap {
constructor(fn) {
this.store = [];
this.fn = fn;
}
peak() {
return this.store[0];
}
size() {
return this.store.length;
}
pop() {
if (this.store.length < 2) {
return this.store.pop();
}
const result = this.store[0];
this.store[0] = this.store.pop();
this.heapifyDown(0);
return result;
}
push(val) {
this.store.push(val);
this.heapifyUp(this.store.length - 1);
}
heapifyUp(child) {
while (child) {
const parent = Math.floor((child - 1) / 2);
if (this.shouldSwap(child, parent)) {
[this.store[child], this.store[parent]] = [this.store[parent], this.store[child]]
child = parent;
} else {
return child;
}
}
}
heapifyDown(parent) {
while (true) {
let [child, child2] = [1,2].map((x) => parent * 2 + x).filter((x) => x < this.size());
if (this.shouldSwap(child2, child)) {
child = child2
}
if (this.shouldSwap(child, parent)) {
[this.store[child], this.store[parent]] = [this.store[parent], this.store[child]]
parent = child;
} else {
return parent;
}
}
}
shouldSwap(child, parent) {
return child && this.fn(this.store[child], this.store[parent]);
}
}