@@ -105,3 +105,154 @@ Trie.prototype.stringsStartingWith = function (prefix) {
105
105
traverse ( curr , prefix )
106
106
return results
107
107
}
108
+
109
+ // another
110
+
111
+ class TrieNode {
112
+ constructor ( ) {
113
+ this . children = new Map ( )
114
+ this . counts = new Map ( )
115
+ this . isWord = false
116
+ }
117
+ }
118
+
119
+ class Pair {
120
+ constructor ( s , c ) {
121
+ this . str = s
122
+ this . cnt = c
123
+ }
124
+ }
125
+
126
+ /**
127
+ * @param {string[] } sentences
128
+ * @param {number[] } times
129
+ */
130
+ const AutocompleteSystem = function ( sentences , times ) {
131
+ this . root = new TrieNode ( )
132
+ this . prefix = ''
133
+ for ( let i = 0 , n = sentences . length ; i < n ; i ++ ) {
134
+ this . add ( sentences [ i ] , times [ i ] )
135
+ }
136
+ }
137
+
138
+ AutocompleteSystem . prototype . add = function ( str , cnt ) {
139
+ let cur = this . root
140
+ for ( const ch of str ) {
141
+ let next = cur . children . get ( ch )
142
+ if ( next == null ) {
143
+ next = new TrieNode ( )
144
+ cur . children . set ( ch , next )
145
+ }
146
+ cur = next
147
+ cur . counts . set ( str , ( cur . counts . get ( str ) || 0 ) + cnt )
148
+ }
149
+ cur . isWord = true
150
+ }
151
+
152
+ /**
153
+ * @param {character } c
154
+ * @return {string[] }
155
+ */
156
+ AutocompleteSystem . prototype . input = function ( c ) {
157
+ if ( c === '#' ) {
158
+ this . add ( this . prefix , 1 )
159
+ this . prefix = ''
160
+ return [ ]
161
+ }
162
+ this . prefix += c
163
+ let cur = this . root
164
+ for ( const ch of this . prefix ) {
165
+ const next = cur . children . get ( ch )
166
+ if ( next == null ) {
167
+ return [ ]
168
+ }
169
+ cur = next
170
+ }
171
+ const pq = new PriorityQueue ( ( a , b ) =>
172
+ a . cnt === b . cnt ? a . str . localeCompare ( b . str ) < 0 : a . cnt > b . cnt
173
+ )
174
+
175
+ for ( const s of cur . counts . keys ( ) ) {
176
+ pq . push ( new Pair ( s , cur . counts . get ( s ) ) )
177
+ }
178
+ const res = [ ]
179
+ for ( let i = 0 ; i < 3 && pq . size ( ) ; i ++ ) {
180
+ res . push ( pq . pop ( ) . str )
181
+ }
182
+
183
+ return res
184
+ }
185
+
186
+ /**
187
+ * Your AutocompleteSystem object will be instantiated and called as such:
188
+ * var obj = new AutocompleteSystem(sentences, times)
189
+ * var param_1 = obj.input(c)
190
+ */
191
+
192
+ class PriorityQueue {
193
+ constructor ( comparator = ( a , b ) => a > b ) {
194
+ this . heap = [ ]
195
+ this . top = 0
196
+ this . comparator = comparator
197
+ }
198
+ size ( ) {
199
+ return this . heap . length
200
+ }
201
+ isEmpty ( ) {
202
+ return this . size ( ) === 0
203
+ }
204
+ peek ( ) {
205
+ return this . heap [ this . top ]
206
+ }
207
+ push ( ...values ) {
208
+ values . forEach ( ( value ) => {
209
+ this . heap . push ( value )
210
+ this . siftUp ( )
211
+ } )
212
+ return this . size ( )
213
+ }
214
+ pop ( ) {
215
+ const poppedValue = this . peek ( )
216
+ const bottom = this . size ( ) - 1
217
+ if ( bottom > this . top ) {
218
+ this . swap ( this . top , bottom )
219
+ }
220
+ this . heap . pop ( )
221
+ this . siftDown ( )
222
+ return poppedValue
223
+ }
224
+ replace ( value ) {
225
+ const replacedValue = this . peek ( )
226
+ this . heap [ this . top ] = value
227
+ this . siftDown ( )
228
+ return replacedValue
229
+ }
230
+
231
+ parent = ( i ) => ( ( i + 1 ) >>> 1 ) - 1
232
+ left = ( i ) => ( i << 1 ) + 1
233
+ right = ( i ) => ( i + 1 ) << 1
234
+ greater = ( i , j ) => this . comparator ( this . heap [ i ] , this . heap [ j ] )
235
+ swap = ( i , j ) => ( [ this . heap [ i ] , this . heap [ j ] ] = [ this . heap [ j ] , this . heap [ i ] ] )
236
+ siftUp = ( ) => {
237
+ let node = this . size ( ) - 1
238
+ while ( node > this . top && this . greater ( node , this . parent ( node ) ) ) {
239
+ this . swap ( node , this . parent ( node ) )
240
+ node = this . parent ( node )
241
+ }
242
+ }
243
+ siftDown = ( ) => {
244
+ let node = this . top
245
+ while (
246
+ ( this . left ( node ) < this . size ( ) && this . greater ( this . left ( node ) , node ) ) ||
247
+ ( this . right ( node ) < this . size ( ) && this . greater ( this . right ( node ) , node ) )
248
+ ) {
249
+ let maxChild =
250
+ this . right ( node ) < this . size ( ) &&
251
+ this . greater ( this . right ( node ) , this . left ( node ) )
252
+ ? this . right ( node )
253
+ : this . left ( node )
254
+ this . swap ( node , maxChild )
255
+ node = maxChild
256
+ }
257
+ }
258
+ }
0 commit comments