Skip to content

Commit 96f0d6e

Browse files
committed
solve #208
1 parent c814693 commit 96f0d6e

File tree

3 files changed

+138
-7
lines changed

3 files changed

+138
-7
lines changed

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,3 +175,4 @@ mod n0204_count_primes;
175175
mod n0205_isomorphic_strings;
176176
mod n0206_reverse_linked_list;
177177
mod n0207_course_schedule;
178+
mod n0208_implement_trie_prefix_tree;

src/n0206_reverse_linked_list.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,18 @@
22
* [206] Reverse Linked List
33
*
44
* Reverse a singly linked list.
5-
*
5+
*
66
* Example:
7-
*
8-
*
7+
*
8+
*
99
* Input: 1->2->3->4->5->NULL
1010
* Output: 5->4->3->2->1->NULL
11-
*
12-
*
11+
*
12+
*
1313
* Follow up:
14-
*
14+
*
1515
* A linked list can be reversed either iteratively or recursively. Could you implement both?
16-
*
16+
*
1717
*/
1818
pub struct Solution {}
1919
use super::util::linked_list::{ListNode, to_list};
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/**
2+
* [208] Implement Trie (Prefix Tree)
3+
*
4+
* Implement a trie with insert, search, and startsWith methods.
5+
*
6+
* Example:
7+
*
8+
*
9+
* Trie trie = new Trie();
10+
*
11+
* trie.insert("apple");
12+
* trie.search("apple"); // returns true
13+
* trie.search("app"); // returns false
14+
* trie.startsWith("app"); // returns true
15+
* trie.insert("app");
16+
* trie.search("app"); // returns true
17+
*
18+
*
19+
* Note:
20+
*
21+
*
22+
* You may assume that all inputs are consist of lowercase letters a-z.
23+
* All inputs are guaranteed to be non-empty strings.
24+
*
25+
*
26+
*/
27+
pub struct Solution {}
28+
29+
// submission codes start here
30+
31+
// use idx 27 as special end character
32+
use std::cell::RefCell;
33+
use std::rc::Rc;
34+
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>>>>,
42+
}
43+
44+
/**
45+
* `&self` means the method takes an immutable reference.
46+
* If you need a mutable reference, change it to `&mut self` instead.
47+
*/
48+
impl Trie {
49+
/** Initialize your data structure here. */
50+
fn new() -> Self {
51+
Trie {
52+
root: Trie::new_node(' '),
53+
}
54+
}
55+
56+
/** insert a word into the trie. */
57+
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();
68+
}
69+
// Add end char
70+
curr.borrow_mut().nodes[26] = Some(Trie::new_node(' '));
71+
}
72+
73+
/** Returns if the word is in the trie. */
74+
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
86+
}
87+
88+
/** Returns if there is any word in the trie that starts with the given prefix. */
89+
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
104+
}
105+
106+
fn new_node(ch: char) -> Rc<RefCell<TrieNode>> {
107+
Rc::new(RefCell::new(TrieNode {
108+
value: ch,
109+
nodes: vec![None; 27],
110+
}))
111+
}
112+
}
113+
114+
// submission codes end
115+
116+
#[cfg(test)]
117+
mod tests {
118+
use super::*;
119+
120+
#[test]
121+
fn test_208() {
122+
let mut trie = Trie::new();
123+
trie.insert("apple".to_owned());
124+
assert_eq!(trie.search("apple".to_owned()), true); // returns true
125+
assert_eq!(trie.search("app".to_owned()), false);
126+
assert_eq!(trie.starts_with("app".to_owned()), true); // returns true
127+
trie.insert("app".to_owned());
128+
assert_eq!(trie.search("app".to_owned()), true); // returns true
129+
}
130+
}

0 commit comments

Comments
 (0)