-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathdesign-add-and-search-words-data-structure.rs
116 lines (96 loc) · 2.7 KB
/
design-add-and-search-words-data-structure.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#![allow(dead_code, unused, unused_variables)]
fn main() {}
struct Solution;
/**
* Your WordDictionary object will be instantiated and called as such:
* let obj = WordDictionary::new();
* obj.add_word(word);
* let ret_2: bool = obj.search(word);
*/
struct WordDictionary {
root: Vec<Option<Box<Node>>>,
}
struct Node {
table: Vec<Option<Box<Node>>>,
// 到此节点是否为一个单词
is_word: bool,
}
impl Node {
fn new(is_word: bool) -> Self {
let mut table = Vec::with_capacity(26);
for _i in 0..26 {
table.push(None);
}
Self { table, is_word }
}
}
/**
* `&self` means the method takes an immutable reference.
* If you need a mutable reference, change it to `&mut self` instead.
*/
impl WordDictionary {
/** Initialize your data structure here. */
fn new() -> Self {
let mut root = Vec::with_capacity(26);
for _i in 0..26 {
root.push(None);
}
Self { root }
}
fn add_word(&mut self, word: String) {
Self::add(&mut self.root[..], word.as_bytes());
}
fn add(table: &mut [Option<Box<Node>>], letter: &[u8]) {
if letter.len() == 0 {
return;
}
let is_word = letter.len() == 1;
let s = if letter[0] == b'.' {
b'a'..=b'z'
} else {
letter[0]..=letter[0]
};
for i in s {
let mut node = table[(i - b'a') as usize].as_mut();
if node.is_none() {
table[(i - b'a') as usize] = Some(Box::new(Node::new(is_word)));
} else {
if is_word {
node.as_mut().unwrap().is_word = is_word;
}
}
Self::add(
table[(i - b'a') as usize].as_mut().unwrap().table.as_mut(),
&letter[1..],
);
}
}
fn search(&self, word: String) -> bool {
Self::search_by_slice(&self.root[..], word.as_bytes())
}
fn search_by_slice(table: &[Option<Box<Node>>], letter: &[u8]) -> bool {
if letter.len() == 0 {
return false;
}
let s = if letter[0] == b'.' {
b'a'..=b'z'
} else {
letter[0]..=letter[0]
};
for i in s {
let node = table[(i - b'a') as usize].as_ref();
if node.is_none() {
continue;
}
if letter.len() == 1 {
if node.as_ref().unwrap().is_word {
return true;
}
}
if Self::search_by_slice(node.as_ref().unwrap().table.as_ref(), &letter[1..]) {
return true;
}
}
false
}
}