Skip to content

Commit 82c99b7

Browse files
committed
Rust: Trie Solutions
1 parent 3d812ba commit 82c99b7

File tree

3 files changed

+209
-0
lines changed

3 files changed

+209
-0
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#[derive(Default)]
2+
struct Trie {
3+
is_word_end: bool,
4+
children: [Option<Box<Trie>>; 26],
5+
}
6+
7+
impl Trie {
8+
9+
fn new() -> Self {
10+
Self{ ..Default::default() }
11+
}
12+
13+
fn insert(&mut self, word: String) {
14+
let mut trie = self;
15+
16+
for c in word.chars(){
17+
trie = trie.children[char_index(c)]
18+
.get_or_insert(Box::new(Trie::new()))
19+
.as_mut();
20+
}
21+
22+
trie.is_word_end = true;
23+
}
24+
25+
fn search(& self, word: String) -> bool {
26+
let mut trie = self;
27+
28+
for c in word.chars(){
29+
if let Some(ref next_trie) = trie.children[char_index(c)]{
30+
trie = next_trie.as_ref();
31+
}else{
32+
return false;
33+
}
34+
}
35+
36+
trie.is_word_end
37+
}
38+
39+
fn starts_with(&self, prefix: String) -> bool {
40+
let mut trie = self;
41+
42+
for c in prefix.chars(){
43+
if let Some(ref next_trie) = trie.children[char_index(c)]{
44+
trie = next_trie.as_ref();
45+
}else{
46+
return false;
47+
}
48+
}
49+
50+
true
51+
}
52+
}
53+
54+
pub fn char_index(c: char) -> usize{
55+
c as usize - 'a' as usize
56+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#[derive(Default)]
2+
struct WordDictionary {
3+
is_word_end: bool,
4+
children: [Option<Box<WordDictionary>>; 26],
5+
}
6+
7+
impl WordDictionary {
8+
9+
fn new() -> Self {
10+
Default::default()
11+
}
12+
13+
fn add_word(&mut self, word: String) {
14+
let mut dict = self;
15+
16+
for c in word.chars(){
17+
dict = dict.children[char_index(c)]
18+
.get_or_insert(Box::new(WordDictionary::new()))
19+
.as_mut();
20+
}
21+
22+
dict.is_word_end = true;
23+
}
24+
25+
fn search_ref(&self, word: &str) -> bool{
26+
let mut dict = self;
27+
28+
for (i, c) in word.chars().enumerate(){
29+
if c == '.'{
30+
let res = dict.children
31+
.iter()
32+
.any(|opt|{
33+
if let Some(ref next_dict) = opt{
34+
next_dict.search_ref(&word[i + 1..])
35+
}else{
36+
false
37+
}
38+
});
39+
40+
return res;
41+
}else{
42+
if let Some(ref next_dict) = dict.children[char_index(c)]{
43+
dict = next_dict.as_ref();
44+
}else{
45+
return false;
46+
}
47+
}
48+
}
49+
50+
dict.is_word_end
51+
}
52+
53+
fn search(&self, word: String) -> bool {
54+
self.search_ref(&word)
55+
}
56+
}
57+
58+
pub fn char_index(c: char) -> usize{
59+
c as usize - 'a' as usize
60+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#[derive(Default, Debug, Clone)]
2+
struct Trie {
3+
is_word_end: bool,
4+
children: [Option<Box<Trie>>; 26],
5+
}
6+
7+
impl Solution {
8+
pub fn find_words(mut board: Vec<Vec<char>>, words: Vec<String>) -> Vec<String> {
9+
let mut trie = Trie::new();
10+
let (m, n) = (board.len(), board[0].len());
11+
12+
for word in words{
13+
trie.insert(word);
14+
}
15+
16+
let mut word = String::new();
17+
let mut res = vec![];
18+
19+
for i in 0..m{
20+
for j in 0..n{
21+
Self::dfs(&mut board, &mut trie, &mut res, &mut word, i, j);
22+
}
23+
}
24+
res
25+
}
26+
27+
pub fn dfs(
28+
board: &mut Vec<Vec<char>>,
29+
mut trie: &mut Trie,
30+
res: &mut Vec<String>,
31+
word: &mut String,
32+
i: usize,
33+
j: usize
34+
){
35+
let (m, n) = (board.len(), board[0].len());
36+
37+
if i!= usize::MAX &&
38+
j!= usize::MAX &&
39+
i < m &&
40+
j < n &&
41+
board[i][j] != '#'
42+
{
43+
let c = board[i][j];
44+
45+
// mark as visited
46+
board[i][j] = '#';
47+
48+
if let Some(ref mut curr_trie) = trie.children[char_index(c)]{
49+
trie = curr_trie.as_mut();
50+
51+
word.push(c);
52+
53+
if trie.is_word_end{
54+
res.push(word.clone());
55+
trie.is_word_end = false;
56+
}
57+
58+
for (x, y) in [(i + 1, j), (i - 1, j), (i, j + 1), (i, j - 1)]{
59+
Self::dfs(board, trie, res, word, x, y);
60+
}
61+
62+
word.pop();
63+
64+
}
65+
66+
board[i][j] = c;
67+
68+
}
69+
}
70+
}
71+
72+
impl Trie {
73+
74+
fn new() -> Self {
75+
Default::default()
76+
}
77+
78+
fn insert(&mut self, word: String) {
79+
let mut trie = self;
80+
81+
for c in word.chars(){
82+
trie = trie.children[char_index(c)]
83+
.get_or_insert(Box::new(Trie::new()))
84+
.as_mut();
85+
}
86+
87+
trie.is_word_end = true;
88+
}
89+
}
90+
91+
pub fn char_index(c: char) -> usize{
92+
c as usize - 'a' as usize
93+
}

0 commit comments

Comments
 (0)