@@ -44,3 +44,114 @@ var suggestedProducts = function(products, searchWord) {
44
44
45
45
return result ;
46
46
} ;
47
+
48
+ /**
49
+ * DFS - Trie
50
+ * Time O(N * M) | Space O(N)
51
+ * https://leetcode.com/problems/search-suggestions-system/
52
+ * @param {string[] } products
53
+ * @param {string } searchWord
54
+ * @return {string[][] }
55
+ */
56
+ var suggestedProducts1 = ( products , searchWord ) => new Trie ( )
57
+ . buildTrie ( products )
58
+ . searchWord ( searchWord ) ;
59
+
60
+ class Node {
61
+ constructor ( ) {
62
+ this . children = new Map ( ) ;
63
+ this . isWord = false ;
64
+ }
65
+ } ;
66
+
67
+ class Trie {
68
+ constructor ( ) {
69
+ this . root = new Node ( ) ;
70
+ }
71
+
72
+ buildTrie ( products ) {
73
+ for ( const word of products ) {
74
+ this . insert ( word ) ;
75
+ }
76
+
77
+ return this ;
78
+ }
79
+
80
+ insert ( word , { root : node } = this ) {
81
+ for ( const char of word . split ( '' ) ) {
82
+ const child = ( node . children . get ( char ) ?? new Node ( ) ) ;
83
+
84
+ node . children . set ( char , child ) ;
85
+
86
+ node = child ;
87
+ }
88
+
89
+ node . isWord = true ;
90
+ }
91
+
92
+ searchWord ( searchWord , buffer = [ ] , suggestions = [ ] ) {
93
+ for ( const char of searchWord . split ( '' ) ) {
94
+ const prefix = this . getPrefix ( buffer , char ) ;
95
+ const words = this . getSuggestions ( prefix ) ;
96
+
97
+ suggestions . push ( words ) ;
98
+ }
99
+
100
+ return suggestions ;
101
+ }
102
+
103
+ getPrefix ( buffer , char ) {
104
+ buffer . push ( char ) ;
105
+
106
+ return buffer . join ( '' ) ;
107
+ }
108
+
109
+ getSuggestions ( prefix , words = [ ] ) {
110
+ const node = this . getPrefixNode ( prefix ) ;
111
+
112
+ const isInvalidPrefix = ( node === null ) ;
113
+ if ( isInvalidPrefix ) return words
114
+
115
+ return this . search ( node , prefix , words ) ;
116
+ }
117
+
118
+ getPrefixNode ( prefix , { root : node } = this ) {
119
+ for ( const char of prefix . split ( '' ) ) {
120
+ const child = ( node . children . get ( char ) ?? null ) ;
121
+
122
+ const isLeafNode = ( child === null ) ;
123
+ if ( isLeafNode ) return null ;
124
+
125
+ node = child ;
126
+ }
127
+
128
+ return node ;
129
+ }
130
+
131
+ search ( node , word , words ) {
132
+ const isBaseCase = ( words . length === 3 ) ;
133
+ if ( isBaseCase ) return words ;
134
+
135
+ if ( node . isWord ) words . push ( word ) ;
136
+
137
+ return this . dfs ( node , word , words ) ;
138
+ }
139
+
140
+ dfs ( node , word , words ) {
141
+ for ( const char of this . getChars ( ) ) {
142
+ const child = ( node . children . get ( char ) ?? null ) ;
143
+
144
+ const isLeafNode = ( child === null ) ;
145
+ if ( isLeafNode ) continue ;
146
+
147
+ this . search ( child , ( word + char ) , words ) ;
148
+ }
149
+
150
+ return words ;
151
+ }
152
+
153
+ getChars ( ) {
154
+ return new Array ( 26 ) . fill ( )
155
+ . map ( ( _ , index ) => String . fromCharCode ( ( index + 97 ) ) ) ;
156
+ }
157
+ } ;
0 commit comments