Given a list of words (without duplicates), please write a program that returns all concatenated words in the given list of words.
A concatenated word is defined as a string that is comprised entirely of at least two shorter words in the given array.
Example:
Input: ["cat","cats","catsdogcats","dog","dogcatsdog","hippopotamuses","rat","ratcatdogcat"] Output: ["catsdogcats","dogcatsdog","ratcatdogcat"] Explanation: "catsdogcats" can be concatenated by "cats", "dog" and "cats"; "dogcatsdog" can be concatenated by "dog", "cats" and "dog"; "ratcatdogcat" can be concatenated by "rat", "cat", "dog" and "cat".
思路:先把单词insert into trie,好判断是否包含一个string,然后用trie 的root,来做DFS,每次找到一个单词,继续递归,index前进,一直到word.length() 同时count >=2代表是我想要的;注意:cur还是在走,但是每次是要从root开始搜单词;cur = root;
class Solution {
private class TrieNode {
public TrieNode[] children;
public boolean isword;
public String word;
public TrieNode () {
this.children = new TrieNode[26];
this.isword = false;
this.word = null;
}
}
private class Trie {
public TrieNode root;
public Trie () {
this.root = new TrieNode();
}
public void insert(String word) {
TrieNode cur = root;
for(int i = 0; i < word.length(); i++) {
char c = word.charAt(i);
if(cur.children[c - 'a'] == null) {
cur.children[c - 'a'] = new TrieNode();
}
cur = cur.children[c - 'a'];
}
cur.isword = true;
cur.word = word;
}
}
public List<String> findAllConcatenatedWordsInADict(String[] words) {
List<String> list = new ArrayList<String>();
Trie trie = new Trie();
for(String word: words) {
trie.insert(word);
}
for(String word: words) {
if(concatenate(trie.root, word, 0, 0)) {
list.add(word);
}
}
return list;
}
private boolean concatenate(TrieNode root, String word, int index, int count) {
if(index == word.length()) {
// 用count记录遇见了几个单词;
return count >= 2;
}
TrieNode cur = root;
for(int i = index; i < word.length(); i++) {
char c = word.charAt(i);
if(cur.children[c - 'a'] == null) {
return false;
}
cur = cur.children[c - 'a'];
if(cur.isword) {
// 每次判断单词,都要从root开始判断,所以传入的参数始终是root;
if(concatenate(root, word, i + 1 , count + 1)) {
return true;
}
}
}
return false;
}
}