1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| class Solution { private static class Trie { private Trie[] children; private boolean end;
public Trie() { this.children = new Trie[26]; this.end = false; } }
private void insertToTrie(String word, Trie trie) { for (int i = 0; i < word.length(); i++) { int index = word.charAt(i) - 'a'; if (trie.children[index] == null) { trie.children[index] = new Trie(); } trie = trie.children[index]; }
trie.end = true; }
public List<String> findAllConcatenatedWordsInADict(String[] words) { Arrays.sort(words, Comparator.comparingInt(String::length));
List<String> concatenatedWordList = new ArrayList<>(); Trie trie = new Trie(); for (String word : words) { if (word.length() == 0) { continue; }
boolean[] visited = new boolean[word.length()]; if (isConcatenated(trie, word, visited, 0)) { concatenatedWordList.add(word); } else { insertToTrie(word, trie); }
}
return concatenatedWordList; }
private boolean isConcatenated(Trie trie, String word, boolean[] visited, int startIndex) { if (startIndex == word.length()) { return true; }
if (visited[startIndex]) { return false; } visited[startIndex] = true;
Trie node = trie; for (int i = startIndex; i < word.length(); i++) { int index = word.charAt(i) - 'a'; node = node.children[index]; if (node == null) { return false; } if (node.end && isConcatenated(trie, word, visited, i + 1)) { return true; } }
return false; } }
|