Skip to content

Commit 8c54083

Browse files
authored
Update 313-super-ugly-number.js
1 parent a48579e commit 8c54083

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed

313-super-ugly-number.js

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,95 @@ const nthSuperUglyNumber = function(n, primes) {
2020
}
2121
return arr[n - 1]
2222
}
23+
24+
// another
25+
26+
/**
27+
* @param {number} n
28+
* @param {number[]} primes
29+
* @return {number}
30+
*/
31+
const nthSuperUglyNumber = function(n, primes) {
32+
const ugly = Array(n).fill(0)
33+
const pq = new PriorityQueue((a, b) => a[0] < b[0])
34+
35+
for(let i = 0; i < primes.length; i++) pq.push([primes[i], 1, primes[i]])
36+
ugly[0] = 1
37+
for(let i = 1; i < n; i++) {
38+
ugly[i] = pq.peek()[0]
39+
while(pq.peek()[0] === ugly[i]) {
40+
const next = pq.pop()
41+
pq.push([next[2] * ugly[next[1]], next[1] + 1, next[2]])
42+
}
43+
}
44+
45+
return ugly[n - 1]
46+
};
47+
48+
class PriorityQueue {
49+
constructor(comparator = (a, b) => a > b) {
50+
this.heap = []
51+
this.top = 0
52+
this.comparator = comparator
53+
}
54+
size() {
55+
return this.heap.length
56+
}
57+
isEmpty() {
58+
return this.size() === 0
59+
}
60+
peek() {
61+
return this.heap[this.top]
62+
}
63+
push(...values) {
64+
values.forEach((value) => {
65+
this.heap.push(value)
66+
this.siftUp()
67+
})
68+
return this.size()
69+
}
70+
pop() {
71+
const poppedValue = this.peek()
72+
const bottom = this.size() - 1
73+
if (bottom > this.top) {
74+
this.swap(this.top, bottom)
75+
}
76+
this.heap.pop()
77+
this.siftDown()
78+
return poppedValue
79+
}
80+
replace(value) {
81+
const replacedValue = this.peek()
82+
this.heap[this.top] = value
83+
this.siftDown()
84+
return replacedValue
85+
}
86+
87+
parent = (i) => ((i + 1) >>> 1) - 1
88+
left = (i) => (i << 1) + 1
89+
right = (i) => (i + 1) << 1
90+
greater = (i, j) => this.comparator(this.heap[i], this.heap[j])
91+
swap = (i, j) => ([this.heap[i], this.heap[j]] = [this.heap[j], this.heap[i]])
92+
siftUp = () => {
93+
let node = this.size() - 1
94+
while (node > this.top && this.greater(node, this.parent(node))) {
95+
this.swap(node, this.parent(node))
96+
node = this.parent(node)
97+
}
98+
}
99+
siftDown = () => {
100+
let node = this.top
101+
while (
102+
(this.left(node) < this.size() && this.greater(this.left(node), node)) ||
103+
(this.right(node) < this.size() && this.greater(this.right(node), node))
104+
) {
105+
let maxChild =
106+
this.right(node) < this.size() &&
107+
this.greater(this.right(node), this.left(node))
108+
? this.right(node)
109+
: this.left(node)
110+
this.swap(node, maxChild)
111+
node = maxChild
112+
}
113+
}
114+
}

0 commit comments

Comments
 (0)