class Solution {
static class Trie {
int[][] son = new int[20][26];
int[] cnt = new int[20];
int idx = 0;
public void insert(char[] str) {
int p = 0;
for (int i = 0; i < str.length; i ++) {
int u = str[i] - 'a';
if (son[p][u] == 0) son[p][u] = ++idx;
p = son[p][u];
}
cnt[p] ++;
}
public int query(char[] str) {
int p = 0;
for (int i = 0; i < str.length; i ++) {
int u = str[i] - 'a';
if (son[p][u] == 0) return 0;
p = son[p][u];
}
return cnt[p];
}
}
List<String> ans = new ArrayList<>();
public List<String> wordBreak(String s, List<String> wordDict) {
Trie trie = new Trie();
for (String dict : wordDict) {
trie.insert(dict.toCharArray());
}
dfs(s, s.length(), 0, trie, new ArrayList<String>());
return ans;
}
public void dfs(String word, int len, int index, Trie trie, ArrayList<String> list) {
if (index == len) {
ans.add(String.join(" ", new ArrayList(list)));
return;
}
for (int i = index + 1; i <= len; i ++) {
String str = word.substring(index, i);
if (trie.query(str.toCharArray()) > 0) {
list.add(str);
dfs(word, len, i, trie, list);
list.remove(list.size() - 1);
}
}
}
}