@@ -28,17 +28,10 @@ pub struct Solution {}
28
28
29
29
// submission codes start here
30
30
31
- // use idx 27 as special end character
32
- use std:: cell:: RefCell ;
33
- use std:: rc:: Rc ;
31
+ #[ derive( Default ) ]
34
32
struct Trie {
35
- root : Rc < RefCell < TrieNode > > ,
36
- }
37
-
38
- #[ derive( PartialEq , Eq , Debug , Clone ) ]
39
- struct TrieNode {
40
- value : char ,
41
- nodes : Vec < Option < Rc < RefCell < TrieNode > > > > ,
33
+ is_end : bool ,
34
+ nodes : [ Option < Box < Trie > > ; 26 ] ,
42
35
}
43
36
44
37
/**
@@ -48,66 +41,35 @@ struct TrieNode {
48
41
impl Trie {
49
42
/** Initialize your data structure here. */
50
43
fn new ( ) -> Self {
51
- Trie {
52
- root : Trie :: new_node ( ' ' ) ,
53
- }
44
+ Default :: default ( )
54
45
}
55
46
56
47
/** insert a word into the trie. */
57
48
fn insert ( & mut self , word : String ) {
58
- let mut curr = self . root . clone ( ) ;
59
- for ch in word. chars ( ) {
60
- let idx = Trie :: to_idx ( ch) ;
61
- if let Some ( node) = curr. clone ( ) . borrow ( ) . nodes [ idx] . clone ( ) {
62
- curr = node;
63
- continue ;
64
- }
65
- let next = Some ( Trie :: new_node ( ch) ) ;
66
- curr. borrow_mut ( ) . nodes [ idx] = next. clone ( ) ;
67
- curr = next. clone ( ) . unwrap ( ) ;
49
+ let mut curr = self ;
50
+
51
+ for i in word. chars ( ) . map ( |ch| ( ch as u8 - 'a' as u8 ) as usize ) {
52
+ curr = curr. nodes [ i] . get_or_insert_with ( || Box :: new ( Trie :: new ( ) ) ) ;
68
53
}
69
- // Add end char
70
- curr. borrow_mut ( ) . nodes [ 26 ] = Some ( Trie :: new_node ( ' ' ) ) ;
54
+ curr. is_end = true ;
71
55
}
72
56
73
57
/** Returns if the word is in the trie. */
74
58
fn search ( & self , word : String ) -> bool {
75
- let mut curr = self . root . clone ( ) ;
76
- for ch in word. chars ( ) {
77
- let idx = Trie :: to_idx ( ch) ;
78
- if let Some ( node) = curr. clone ( ) . borrow ( ) . nodes [ idx] . clone ( ) {
79
- curr = node;
80
- } else {
81
- return false ;
82
- }
83
- }
84
- let searched = curr. borrow ( ) . nodes [ 26 ] . is_some ( ) ;
85
- searched
59
+ self . find ( word) . map_or ( false , |t| t. is_end )
86
60
}
87
61
88
62
/** Returns if there is any word in the trie that starts with the given prefix. */
89
63
fn starts_with ( & self , prefix : String ) -> bool {
90
- let mut curr = self . root . clone ( ) ;
91
- for ch in prefix. chars ( ) {
92
- let idx = Trie :: to_idx ( ch) ;
93
- if let Some ( node) = curr. clone ( ) . borrow ( ) . nodes [ idx] . clone ( ) {
94
- curr = node;
95
- } else {
96
- return false ;
97
- }
98
- }
99
- true
100
- }
101
-
102
- fn to_idx ( ch : char ) -> usize {
103
- ( ch as u8 - 'a' as u8 ) as usize
64
+ self . find ( prefix) . is_some ( )
104
65
}
105
66
106
- fn new_node ( ch : char ) -> Rc < RefCell < TrieNode > > {
107
- Rc :: new ( RefCell :: new ( TrieNode {
108
- value : ch,
109
- nodes : vec ! [ None ; 27 ] ,
110
- } ) )
67
+ fn find ( & self , word : String ) -> Option < & Trie > {
68
+ let mut curr = self ;
69
+ for i in word. chars ( ) . map ( |ch| ( ch as u8 - 'a' as u8 ) as usize ) {
70
+ curr = curr. nodes [ i] . as_ref ( ) ?;
71
+ }
72
+ Some ( curr)
111
73
}
112
74
}
113
75
0 commit comments