@@ -20,3 +20,95 @@ const nthSuperUglyNumber = function(n, primes) {
20
20
}
21
21
return arr [ n - 1 ]
22
22
}
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