20240701 Finished

This commit is contained in:
jackfiled 2024-07-01 11:43:50 +08:00
parent d57286d7c8
commit 5970f4fb97
3 changed files with 133 additions and 1 deletions

View File

@ -162,4 +162,5 @@ mod p210_course_schedule_ii;
mod p909_snakes_and_ladders; mod p909_snakes_and_ladders;
mod p433_minimum_genetic_mutation; mod p433_minimum_genetic_mutation;
mod p127_word_ladder; mod p127_word_ladder;
mod p208_implement_trie_prefix_tree; mod p208_implement_trie_prefix_tree;
mod p211_design_add_and_search_words_data_structure;

View File

@ -0,0 +1,131 @@
/**
* [211] Design Add and Search Words Data Structure
*/
pub struct Solution {}
// submission codes start here
use std::{rc::Rc, cell::RefCell, collections::{HashMap, VecDeque}};
struct TireNode {
is_word: bool,
next: HashMap<char, Rc<RefCell<TireNode>>>,
}
impl TireNode {
fn new(is_word: bool) -> Self {
TireNode {
is_word,
next: HashMap::new(),
}
}
}
struct WordDictionary {
dummy_head: Rc<RefCell<TireNode>>,
}
/**
* `&self` means the method takes an immutable reference.
* If you need a mutable reference, change it to `&mut self` instead.
*/
impl WordDictionary {
fn new() -> Self {
WordDictionary {
dummy_head: Rc::new(RefCell::new(TireNode::new(false)))
}
}
fn add_word(&self, word: String) {
let mut node = Rc::clone(&self.dummy_head);
for (i, c) in word.chars().enumerate() {
if node.borrow().next.contains_key(&c) {
if i == word.len() - 1 {
node.borrow().next
.get(&c)
.unwrap()
.borrow_mut().is_word = true;
}
} else {
if i == word.len() - 1 {
node.borrow_mut().next.insert(c, Rc::new(RefCell::new(TireNode::new(true))));
} else {
node.borrow_mut().next.insert(c, Rc::new(RefCell::new(TireNode::new(false))));
}
}
let tmp_node = Rc::clone(node.borrow().next.get(&c).unwrap());
node = tmp_node;
}
}
fn search(&self, word: String) -> bool {
let mut queue = VecDeque::new();
queue.push_back(Rc::clone(&self.dummy_head));
for (i, c) in word.chars().enumerate() {
if queue.is_empty() {
break;
}
let length = queue.len();
for _ in 0..length {
let node = queue.pop_front().unwrap();
if i == word.len() - 1 {
if c == '.' && node.borrow().next.iter().any(|(_, n)| {
n.borrow().is_word
}) {
return true;
}
if let Some(n) = node.borrow().next.get(&c) {
if n.borrow().is_word {
return true;
}
}
} else {
if c == '.' {
for n in node.borrow().next.values() {
queue.push_back(Rc::clone(n));
}
} else {
if let Some(n) = node.borrow().next.get(&c) {
queue.push_back(Rc::clone(n));
}
}
}
}
}
false
}
}
/**
* 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);
*/
// submission codes end
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_211() {
let mut dict = WordDictionary::new();
dict.add_word("bad".to_owned());
dict.add_word("dad".to_owned());
dict.add_word("add".to_owned());
assert!(!dict.search("pad".to_owned()));
assert!(!dict.search("a".to_owned()));
assert!(dict.search("dad".to_owned()));
assert!(dict.search(".ad".to_owned()));
}
}