|
| 1 | +/** |
| 2 | + * @param {number} capacity |
| 3 | + */ |
| 4 | +const DinnerPlates = function (capacity) { |
| 5 | + this.capacity = capacity |
| 6 | + this.stacks = [] |
| 7 | + this.pq = new PriorityQueue() |
| 8 | +} |
| 9 | + |
| 10 | +/** |
| 11 | + * @param {number} val |
| 12 | + * @return {void} |
| 13 | + */ |
| 14 | +DinnerPlates.prototype.push = function (val) { |
| 15 | + if (this.pq.isEmpty()) { |
| 16 | + if ( |
| 17 | + this.stacks.length > 0 && |
| 18 | + this.stacks[this.stacks.length - 1].length < this.capacity |
| 19 | + ) { |
| 20 | + this.stacks[this.stacks.length - 1].push(val) |
| 21 | + } else { |
| 22 | + this.stacks.push([]) |
| 23 | + this.stacks[this.stacks.length - 1].push(val) |
| 24 | + } |
| 25 | + } else { |
| 26 | + const num = this.pq.pop() |
| 27 | + this.stacks[num].push(val) |
| 28 | + } |
| 29 | +} |
| 30 | + |
| 31 | +/** |
| 32 | + * @return {number} |
| 33 | + */ |
| 34 | +DinnerPlates.prototype.pop = function () { |
| 35 | + while ( |
| 36 | + this.stacks.length > 0 && |
| 37 | + this.stacks[this.stacks.length - 1].length === 0 |
| 38 | + ) { |
| 39 | + const len = this.stacks.length - 1 |
| 40 | + while (!this.pq.isEmpty() && this.pq.peek() >= len) { |
| 41 | + this.pq.pop() |
| 42 | + } |
| 43 | + this.stacks.pop() |
| 44 | + } |
| 45 | + if (this.stacks.length === 0) { |
| 46 | + return -1 |
| 47 | + } else { |
| 48 | + return this.stacks[this.stacks.length - 1].pop() |
| 49 | + } |
| 50 | +} |
| 51 | + |
| 52 | +/** |
| 53 | + * @param {number} index |
| 54 | + * @return {number} |
| 55 | + */ |
| 56 | +DinnerPlates.prototype.popAtStack = function (index) { |
| 57 | + const st = this.stacks[index] |
| 58 | + |
| 59 | + if (st && st.length > 0) { |
| 60 | + this.pq.push(index) |
| 61 | + return st.pop() |
| 62 | + } |
| 63 | + |
| 64 | + return -1 |
| 65 | +} |
| 66 | + |
| 67 | +/** |
| 68 | + * Your DinnerPlates object will be instantiated and called as such: |
| 69 | + * var obj = new DinnerPlates(capacity) |
| 70 | + * obj.push(val) |
| 71 | + * var param_2 = obj.pop() |
| 72 | + * var param_3 = obj.popAtStack(index) |
| 73 | + */ |
| 74 | +class PriorityQueue { |
| 75 | + constructor(len, compare) { |
| 76 | + this.compare = (a, b) => { |
| 77 | + return a < b |
| 78 | + } |
| 79 | + this.last = 0 |
| 80 | + this.arr = [] |
| 81 | + } |
| 82 | + push(val) { |
| 83 | + this.last++ |
| 84 | + this.arr[this.last] = val |
| 85 | + this.up(this.last) |
| 86 | + } |
| 87 | + pop() { |
| 88 | + if (this.isEmpty()) { |
| 89 | + return null |
| 90 | + } |
| 91 | + const res = this.arr[1] |
| 92 | + this.swap(1, this.last) |
| 93 | + this.last-- |
| 94 | + this.down(1) |
| 95 | + return res |
| 96 | + } |
| 97 | + up(lo) { |
| 98 | + while (lo > 1) { |
| 99 | + const currEl = this.arr[lo] |
| 100 | + const parent = Math.floor(lo / 2) |
| 101 | + const parentEl = this.arr[parent] |
| 102 | + if (this.compare(currEl, parentEl)) { |
| 103 | + this.swap(lo, parent) |
| 104 | + } else { |
| 105 | + break |
| 106 | + } |
| 107 | + lo = parent |
| 108 | + } |
| 109 | + } |
| 110 | + down(hi) { |
| 111 | + while (hi * 2 <= this.last) { |
| 112 | + const currEl = this.arr[hi] |
| 113 | + let nextEl = this.arr[hi * 2] |
| 114 | + let nextIndex = hi * 2 |
| 115 | + if ( |
| 116 | + hi * 2 + 1 <= this.last && |
| 117 | + this.compare(this.arr[hi * 2 + 1], nextEl) |
| 118 | + ) { |
| 119 | + nextIndex = hi * 2 + 1 |
| 120 | + nextEl = this.arr[nextIndex] |
| 121 | + } |
| 122 | + if (this.compare(nextEl, currEl)) { |
| 123 | + this.swap(hi, nextIndex) |
| 124 | + } else { |
| 125 | + break |
| 126 | + } |
| 127 | + hi = nextIndex |
| 128 | + } |
| 129 | + } |
| 130 | + swap(i, j) { |
| 131 | + const temp = this.arr[i] |
| 132 | + this.arr[i] = this.arr[j] |
| 133 | + this.arr[j] = temp |
| 134 | + } |
| 135 | + peek() { |
| 136 | + if (this.isEmpty()) { |
| 137 | + return null |
| 138 | + } |
| 139 | + return this.arr[1] |
| 140 | + } |
| 141 | + isEmpty() { |
| 142 | + return this.last < 1 |
| 143 | + } |
| 144 | +} |
0 commit comments