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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
| class Solution {
public List<String> findAllConcatenatedWordsInADict(String[] words) {
Set<String> wordSet = new HashSet<>(Arrays.asList(words));
TrieNode root = new TrieNode('#');
List<String> res = new ArrayList<>();
for (String word: words) {
TrieNode node = root;
for (int i = 0; i < word.length(); i++) {
char c = word.charAt(i);
if (node.children[c - 'a'] == null) {
node.children[c - 'a'] = new TrieNode(c);
}
node = node.children[c - 'a'];
}
if (node != root) {
node.isWord = true;
}
}
for (String word: words) {
if (dfs(root, word.toCharArray(), 0, word.length())) {
res.add(word);
}
}
print(root, 0);
return res;
}
boolean isWord(TrieNode root, char[] chars, int left, int right) {
TrieNode node = root;
for (int i = left; i < right; i++) {
char c = chars[i];
if (node.children[c - 'a'] != null) {
node = node.children[c - 'a'];
} else {
return false;
}
}
if (node.isWord) {
// System.out.println("\t " + new String(Arrays.copyOfRange(chars, left, right)) + " is word");
}
return node.isWord;
}
boolean dfs(TrieNode node, char[] chars, int left, int right) {
// System.out.println("word = " + new String(Arrays.copyOfRange(chars, left, right)));
for (int i = left; i < right; i++) {
// System.out.println("\t prefix = " + new String(Arrays.copyOfRange(chars, left, i)));
if (isWord(node, chars, left, i)) {
// System.out.println("\t suffix = " + new String(Arrays.copyOfRange(chars, i, right)));
if (isWord(node, chars, i, right) || dfs(node, chars, i, right)) {
markWord(node, chars, i, right);
return true;
}
}
}
return false;
}
void print(TrieNode node, int begin) {
System.out.println(" ".repeat(begin) + node.val + (node.isWord ? "*": ""));
for(TrieNode child: node.children) {
if (child != null) print(child, begin + 2);
}
}
void markWord(TrieNode root, char[] chars, int left, int right) {
TrieNode node = root;
for (int i = left; i < right; i++) {
char c = chars[i];
if (node.children[c - 'a'] != null) {
node = node.children[c - 'a'];
} else {
return;
}
}
node.isWord = true;
// System.out.println("\t mark word = " + new String(Arrays.copyOfRange(chars, left, right)));
}
}
class TrieNode {
char val;
TrieNode[] children = new TrieNode[26];
boolean isWord;
public TrieNode(char val) {
this.val = val;
}
}
|