@@ -28,17 +28,10 @@ pub struct Solution {}
2828
2929// submission codes start here
3030
31- // use idx 27 as special end character
32- use std:: cell:: RefCell ;
33- use std:: rc:: Rc ;
31+ #[ derive( Default ) ]
3432struct 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 ] ,
4235}
4336
4437/**
@@ -48,66 +41,35 @@ struct TrieNode {
4841impl Trie {
4942 /** Initialize your data structure here. */
5043 fn new ( ) -> Self {
51- Trie {
52- root : Trie :: new_node ( ' ' ) ,
53- }
44+ Default :: default ( )
5445 }
5546
5647 /** insert a word into the trie. */
5748 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 ( ) ) ) ;
6853 }
69- // Add end char
70- curr. borrow_mut ( ) . nodes [ 26 ] = Some ( Trie :: new_node ( ' ' ) ) ;
54+ curr. is_end = true ;
7155 }
7256
7357 /** Returns if the word is in the trie. */
7458 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 )
8660 }
8761
8862 /** Returns if there is any word in the trie that starts with the given prefix. */
8963 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 ( )
10465 }
10566
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)
11173 }
11274}
11375
0 commit comments