1+ class TrieNode {
2+ children : Map < string , TrieNode > ;
3+ isEndOfWord : boolean ;
4+
5+ constructor ( ) {
6+ this . children = new Map < string , TrieNode > ( ) ;
7+ this . isEndOfWord = false ;
8+ }
9+ }
10+
11+ class Trie {
12+ private root : TrieNode ;
13+
14+ constructor ( ) {
15+ this . root = new TrieNode ( ) ;
16+ }
17+
18+ insert ( word : string ) : void {
19+ let node = this . root ;
20+ for ( let char of word ) {
21+ if ( ! node . children . has ( char ) ) {
22+ node . children . set ( char , new TrieNode ( ) ) ;
23+ }
24+ node = node . children . get ( char ) ! ;
25+ }
26+ node . isEndOfWord = true ;
27+ }
28+
29+ search ( word : string ) : boolean {
30+ let node = this . root ;
31+ for ( let char of word ) {
32+ if ( ! node . children . has ( char ) ) {
33+ return false ;
34+ }
35+ node = node . children . get ( char ) ! ;
36+ }
37+ return node . isEndOfWord ;
38+ }
39+
40+ startsWith ( prefix : string ) : boolean {
41+ let node = this . root ;
42+ for ( let char of prefix ) {
43+ if ( ! node . children . has ( char ) ) {
44+ return false ;
45+ }
46+ node = node . children . get ( char ) ! ;
47+ }
48+ return true ;
49+ }
50+
51+ remove ( word : string ) : boolean {
52+ return this . #removeWord( this . root , word , 0 ) ;
53+ }
54+
55+ #removeWord( node : TrieNode , word : string , index : number ) : boolean {
56+ if ( index === word . length ) {
57+ if ( ! node . isEndOfWord ) return false ;
58+ node . isEndOfWord = false ;
59+ return node . children . size === 0 ;
60+ }
61+
62+ const char = word [ index ] ;
63+ if ( ! node . children . has ( char ) ) {
64+ return false ;
65+ }
66+
67+ const shouldDeleteCurrentNode = this . #removeWord( node . children . get ( char ) ! , word , index + 1 ) ;
68+ if ( shouldDeleteCurrentNode ) {
69+ node . children . delete ( char ) ;
70+ return node . children . size === 0 ;
71+ }
72+
73+ return false ;
74+ }
75+ }
76+
77+ export default Trie ;
0 commit comments