Implement an autocomplete system. That is, given a query string s and a set of all possible query strings, return all strings in the set that have s as a prefix.
For example, given the query string de and the set of strings [dog, deer, deal], return [deer, deal].
Hint: Try preprocessing the dictionary into a more efficient data structure to speed up queries.
We have already seen most of the functions in Implement Trie, and here we will cover wordsByPrefix function.
The algorithm to fetch the word list is almost similar to the one for adding a word
We can use the startsWith function to check if prefix exists in trie. If we get false, we return empty list. Another way to check is we go through prefix word in the trie, and if we encounter null node, we return empty list.
Otherwise run the DFS from prefix point, and till all the leaf nodes.
classTrie {
staticclassTrieNode {
privateboolean isLeaf;
private Map<Character, TrieNode> children =new HashMap<>();
}
public TrieNode root;
/** Initialize your data structure here. */publicTrie() {
this.root=new TrieNode();
}
/** Inserts a word into the trie. */publicvoidinsert(String word) {}
/** Returns if the word is in the trie. */publicbooleansearch(String word) {}
publicbooleanstartsWith(String prefix) {}
public List<String>wordsByPrefix(String prefix) {
List<String> ans =new ArrayList<>();
TrieNode curr =this.root;
// Navigate to the end of the prefixfor (char c: prefix.toCharArray()) {
if (!curr.children.containsKey(c)) {
// If prefix is not present, return empty listreturn ans;
}
curr = curr.children.get(c);
}
// Recursively find all words starting with the given prefix dfs(curr, new StringBuilder(prefix), ans);
return ans;
}
privatevoiddfs(TrieNode node, StringBuilder path, List<String> ans) {
if (node.isLeaf) {
ans.add(path.toString());
}
for (Map.Entry<Character, TrieNode> entry: node.children.entrySet()) {
// For each child, append the char and search deeper path.append(entry.getKey());
dfs(entry.getValue(), path, ans);
// Backtrack to previous state to explore other paths path.deleteCharAt(path.length() - 1);
}
}
}