diff --git a/src/problem/mod.rs b/src/problem/mod.rs index e3d12ea..a0fb807 100644 --- a/src/problem/mod.rs +++ b/src/problem/mod.rs @@ -195,4 +195,5 @@ mod p69_sqrtx; mod p50_powx_n; mod p149_max_points_on_a_line; mod p70_climbing_stairs; -mod p198_house_robber; \ No newline at end of file +mod p198_house_robber; +mod p139_word_break; \ No newline at end of file diff --git a/src/problem/p139_word_break.rs b/src/problem/p139_word_break.rs new file mode 100644 index 0000000..d00987b --- /dev/null +++ b/src/problem/p139_word_break.rs @@ -0,0 +1,88 @@ +/** + * [139] Word Break + */ +pub struct Solution {} + + +// submission codes start here +use std::{rc::Rc, cell::RefCell, collections::HashMap}; + +struct Trie { + is_word: bool, + next: HashMap>>, +} + +impl Trie { + fn new(is_word: bool) -> Rc> { + Rc::new(RefCell::new(Trie { + is_word, + next: HashMap::new(), + })) + } +} + +impl Solution { + pub fn word_break(s: String, word_dict: Vec) -> bool { + let mut root = Trie::new(false); + + // 建立字典树 + for word in &word_dict { + let mut node = Rc::clone(&root); + + 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, Trie::new(true)); + } else { + node.borrow_mut().next.insert(c, Trie::new(false)); + } + } + + let tmp_node = Rc::clone(node.borrow().next.get(&c).unwrap()); + node = tmp_node; + } + } + + let word: Vec = s.chars().collect(); + let n = s.len(); + let mut dp = vec![false; n]; + + for i in 0..n { + if i > 0 && !dp[i - 1] { + continue; + } + + let mut node = Rc::clone(&root); + + let mut pos = i; + while pos < n && node.borrow().next.contains_key(&word[pos]) { + let next_node = Rc::clone(node.borrow().next.get(&word[pos]).unwrap()); + + dp[pos] = next_node.borrow().is_word || dp[pos]; + pos += 1; + node = next_node; + } + } + + dp[n - 1] + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_139() { + assert!(Solution::word_break("leetcode".to_owned(), vec_string!("leet", "code"))); + assert!(Solution::word_break("applepenapple".to_owned(), vec_string!("apple", "pen"))); + assert!(!Solution::word_break("catsandog".to_owned(), vec_string!("cats", "cat", "sand", "and", "cat"))); + assert!(Solution::word_break("aaaaaaa".to_owned(), vec_string!("aaa", "aaaa"))); + } +}