问题一
多次搜索:https://leetcode-cn.com/problems/multi-search-lcci/
思路:使用前缀树保存所有待查找的字符串,然后依次遍历big字符串,将所有子串的前缀查找出来,最后反向找到所有的待查找字符串位置。
public int[][] multiSearch(String big, String[] smalls) {
Trie trie = new Trie();
for (String s : smalls) {
trie.insert(s);
}
Map<String, List<Integer>> map = new HashMap<>();
for (int i = 0; i < big.length(); i++) {
String str = big.substring(i);
List<String> strs = trie.searchTrie(str);
for (String s : strs) {
if (!map.containsKey(s)) {
map.put(s, new LinkedList<>());
}
map.get(s).add(i);
}
}
int[][] result = new int[smalls.length][];
for (int i = 0; i < smalls.length; i++) {
List<Integer> indexs = map.get(smalls[i]);
if (indexs != null) {
result[i] = indexs.stream().mapToInt(Integer::intValue).toArray();
} else {
result[i] = new int[0];
}
}
return result;
}
class Trie {
private Trie[] children;
private String word;
public Trie() {
children = new Trie[26];
word = "";
}
public void insert(String word) {
Trie trie = this;
for (int i = 0; i < word.length(); i++) {
char ch = word.charAt(i);
int index = ch - 'a';
if (trie.children[index] == null) {
trie.children[index] = new Trie();
}
trie = trie.children[index];
}
trie.word = word;
}
private List<String> searchTrie(String word) {
List<String> strs = new LinkedList<>();
Trie trie = this;
for (int i = 0; i < word.length(); i++) {
char ch = word.charAt(i);
int index = ch - 'a';
if (trie.children[index] == null) {
break;
}
trie = trie.children[index];
if (trie.word != null) {
strs.add(trie.word);
}
}
return strs;
}
}
问题二
实现Trie(前缀树):https://leetcode-cn.com/problems/implement-trie-prefix-tree/
class Trie {
private Trie[] children;
private boolean isleaf;
public Trie() {
children = new Trie[26];
isleaf = false;
}
public void insert(String word) {
Trie trie = this;
for (int i = 0; i < word.length(); i++) {
char ch = word.charAt(i);
int index = ch - 'a';
if (trie.children[index] == null) {
trie.children[index] = new Trie();
}
trie = trie.children[index];
}
trie.isleaf = true;
}
public boolean search(String word) {
Trie trie = searchTrie(word);
return trie != null && trie.isleaf;
}
public boolean startsWith(String prefix) {
return searchTrie(prefix) != null;
}
private Trie searchTrie(String word) {
Trie trie = this;
for (int i = 0; i < word.length(); i++) {
char ch = word.charAt(i);
int index = ch - 'a';
if (trie.children[index] == null) {
return null;
}
trie = trie.children[index];
}
return trie;
}
}