|
| 1 | +/// |
| 2 | +#[derive(Default)] |
| 3 | +struct Trie { c: [Option<Box<Self>>; 26], is_word: bool } |
| 4 | + |
| 5 | +impl Solution { |
| 6 | + pub fn find_all_concatenated_words_in_a_dict(mut words: Vec<String>) -> Vec<String> { |
| 7 | + words.sort_by_key(|w| w.len()); |
| 8 | + let mut trie: Trie = Default::default(); |
| 9 | + let mut vis: Vec<isize> = vec![0; words.last().unwrap().len()+1]; |
| 10 | + let mut q: Vec<usize> = vec![]; |
| 11 | + let mut tick = 0; |
| 12 | + let mut ans: Vec<String> = vec![]; |
| 13 | + for ww in words.into_iter() { |
| 14 | + if ww.is_empty() { continue; } |
| 15 | + let w = ww.as_bytes(); |
| 16 | + q.clear(); |
| 17 | + q.push(0); |
| 18 | + tick += 1; |
| 19 | + while let Some(bgn) = q.pop() { |
| 20 | + let mut t: &Trie = &mut trie; |
| 21 | + for i in bgn..w.len() { |
| 22 | + if let Some(t1) = &t.c[(w[i]-b'a') as usize] { |
| 23 | + t = t1; |
| 24 | + if t.is_word && vis[i+1] != tick { |
| 25 | + vis[i+1] = tick; |
| 26 | + q.push(i+1); |
| 27 | + } |
| 28 | + } else { |
| 29 | + break; |
| 30 | + } |
| 31 | + } |
| 32 | + if vis[w.len()] == tick { |
| 33 | + ans.push(ww.clone()); |
| 34 | + break; |
| 35 | + } |
| 36 | + } |
| 37 | + |
| 38 | + let mut t = &mut trie; |
| 39 | + for c in w.iter().map(|ch| (ch-b'a') as usize) { |
| 40 | + t = t.c[c].get_or_insert_with(|| Default::default()); |
| 41 | + } |
| 42 | + t.is_word = true; |
| 43 | + } |
| 44 | + ans |
| 45 | + } |
| 46 | +} |
| 47 | + |
| 48 | +/// memoization |
| 49 | +
|
| 50 | +#[derive(Default)] |
| 51 | +struct Trie { c: [Option<Box<Self>>; 26], is_word: bool } |
| 52 | + |
| 53 | +impl Solution { |
| 54 | + pub fn find_all_concatenated_words_in_a_dict(mut words: Vec<String>) -> Vec<String> { |
| 55 | + struct St<'a> { root: &'a Trie, memo: &'a mut [(isize,bool)], tick: isize, w: &'a [u8] }; |
| 56 | + fn dfs(st: &mut St, mut t: &Trie, bgn: usize) -> bool { |
| 57 | + if st.memo[bgn].0 == st.tick { return st.memo[bgn].1 } |
| 58 | + let w = st.w; |
| 59 | + if w.len() == bgn { return true; } |
| 60 | + let mut ans = false; |
| 61 | + for i in bgn..w.len() { |
| 62 | + if let Some(t1) = &t.c[(w[i]-b'a') as usize] { |
| 63 | + t = t1; |
| 64 | + if t1.is_word && dfs(st, st.root, i+1) { |
| 65 | + ans = true; |
| 66 | + break; |
| 67 | + } |
| 68 | + } else { |
| 69 | + break; |
| 70 | + } |
| 71 | + } |
| 72 | + st.memo[bgn] = (st.tick, ans); |
| 73 | + ans |
| 74 | + } |
| 75 | + |
| 76 | + words.sort_by_key(|w| w.len()); |
| 77 | + let mut trie: Trie = Default::default(); |
| 78 | + let mut memo: Vec<(isize,bool)> = vec![(0, false); words.last().unwrap().len()+1]; |
| 79 | + let mut tick = 0; |
| 80 | + let mut ans: Vec<String> = vec![]; |
| 81 | + for w in words.into_iter() { |
| 82 | + tick += 1; |
| 83 | + let mut st = St { root: &trie, memo: &mut memo, tick, w: w.as_bytes() }; |
| 84 | + if w.len() > 0 && dfs(&mut st, &trie, 0) { |
| 85 | + ans.push(w.to_owned()); |
| 86 | + } |
| 87 | + let mut t = &mut trie; |
| 88 | + for c in w.as_bytes().iter().map(|ch| (ch-b'a') as usize) { |
| 89 | + t = t.c[c].get_or_insert_with(|| Default::default()); |
| 90 | + } |
| 91 | + t.is_word = true; |
| 92 | + } |
| 93 | + ans |
| 94 | + } |
| 95 | +} |
0 commit comments