用两棵Trie的话难度不大,核心是空间换时间的做法,把经过Trie的所有字符串的index存储下来,最后取前缀和后缀匹配list的最大的相等数。
至于用一棵树的做法,我个人觉得比较难想到。
class WordFilter {
Node root1 = new Node();
Node root2 = new Node();
void add(Node node, String word, int pos, int ans) {
node.indexs.add(ans);
if (word.length() == pos) {
return;
}
int index = word.charAt(pos) - 'a';
if (node.next[index] == null) {
node.next[index] = new Node();
}
add(node.next[index], word, pos + 1, ans);
}
public WordFilter(String[] words) {
int n = words.length;
for (int i = 0; i < n; i++) {
String word = words[i];
add(root1, word, 0, i);
add(root2, new StringBuilder(word).reverse().toString(), 0, i);
}
}
List<Integer> find(Node node, String word, int pos) {
if (pos == word.length()) {
return node.indexs;
}
int index = word.charAt(pos) - 'a';
if (node.next[index] == null) {
return Collections.emptyList();
}
return find(node.next[index], word, pos + 1);
}
int findMaxTheSame(List<Integer> ans1, List<Integer> ans2) {
int index = ans1.size() - 1;
for (int i = ans2.size() - 1; i >= 0 && index >= 0; i--) {
int a = ans1.get(index);
int b = ans2.get(i);
if (a == b) {
return a;
} else if (a > b) {
index--;
i++;
}
}
return -1;
}
public int f(String pref, String suff) {
List<Integer> ans1 = find(root1, pref, 0);
List<Integer> ans2 = find(root2, new StringBuilder(suff).reverse().toString(), 0);
return findMaxTheSame(ans1, ans2);
}
}
class Node {
Node[] next = new Node[26];
List<Integer> indexs = new ArrayList<>();
}