/** Initialize your data structure here. */TrieNoderoot;publicTrie(){ root =newTrieNode();}/** Inserts a word into the trie. */publicvoidinsert(String word){TrieNodecurt= root;for(charc:word.toCharArray()){intid= c -'a';if(curt.children[id]==null)curt.children[id]=newTrieNode(); curt =curt.children[id];}curt.isWord=true;}/** Returns if the word is in the trie. */publicbooleansearch(String word){returnfind(word.toCharArray(), root,false);}/** Returns if there is any word in the trie that starts with the given prefix. */publicbooleanstartsWith(String prefix){returnfind(prefix.toCharArray(), root,true);}privatebooleanfind(char[] chars,TrieNode curt,boolean prefix){for(charc: chars){intid= c -'a';if(curt.children[id]==null)returnfalse; curt =curt.children[id];}if(prefix)returntrue;returncurt.isWord;}classTrieNode{TrieNode[] children;boolean isWord =false;TrieNode(){this.children=newTrieNode[26];}}
Build Trie and store index of the string in folder, the index has default value of -1.
BFS to find all parents, offer Tire root to the queue. While queue is not empty, pop nodes with index != -1, which means it is a parent folder. Check if it is children is not null and not 26 (which represent "/"), then it is another valid answer. For example, "/a/b/ca" is not a subfolder of "/a/b/c"
When building Trie, add to the word to the end of Trie node. DFS search on Trie in 4 directions. Set the visited grid to '#' to eliminate revisit, flip it back as DFS completes.
Construct Trie Tree with words provided. When search, count the words which is already found and keep finding the next word from root, return true when total words find is >= 2.
Build Trie with words on the corresponding node. Simultaneously search the Trie and the board to find the word on the node, mark the grid as '#' to indicate visited,erase the word after added to the result. (this is because you only want to find one word if there are duplicates on the grid) Check if the x, y coordinates are out of bound or visited. Add word to the result.
T: O(M(4⋅3 L−1)), where MM is the number of cells in the board and LL is the maximum length of words.
At each TrieNode, set children map and a separate map to count the corresponding word and frequency. Write a function List<String> getTop3() and use max heap to produce the top 3 words in each node.
AutocompleteSystem() takes O(k*l) time. We need to iterate over l sentences each of average length k, to create the trie for the given set of sentences. input() takes O(p+q+m *log m)time. Here, p refers to the length of the sentence
class TrieNode:
def __init__(self):
self.children = {}
self.isEnd = False
class Trie:
def __init__(self):
"""
Initialize your data structure here.
"""
self.root = TrieNode()
def insert(self, word: str) -> None:
"""
Inserts a word into the trie.
"""
curt = self.root
for char in word:
if char not in curt.children:
curt.children[char] = TrieNode()
curt = curt.children[char]
curt.isEnd = True
def search(self, word: str) -> bool:
"""
Returns if the word is in the trie.
"""
curt = self.root
for char in word:
if char not in curt.children:
return False
curt = curt.children[char]
return curt.isEnd
def startsWith(self, prefix: str) -> bool:
"""
Returns if there is any word in the trie that starts with the given prefix.
"""
curt = self.root
for char in prefix:
if char not in curt.children:
return False
curt = curt.children[char]
return True
class TrieNode {
TrieNode[] children = new TrieNode[26];
boolean WordEnd;
public TrieNode() {
for (TrieNode node : children) {
node = null;
}
WordEnd = false;
}
}
/** Initialize your data structure here. */
TrieNode root;
public WordDictionary() {
root = new TrieNode();
}
/** Adds a word into the data structure. */
public void addWord(String word) {
addWord(word, root);
}
private void addWord(String word, TrieNode root) {
TrieNode curt = root;
for (char c : word.toCharArray()) {
int index = c - 'a';
if (curt.children[index] == null) {
curt.children[index] = new TrieNode();
}
curt = curt.children[index];
}
curt.WordEnd = true;
}
/** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */
public boolean search(String word) {
return search(word.toCharArray(), 0, root);
}
private boolean search(char[] chars, int index, TrieNode curt) {
if (index == chars.length) return curt.WordEnd;
if (chars[index] == '.') {
for (TrieNode child : curt.children) {
if (child == null) continue;
if (search(chars, index + 1, child)) return true;
}
} else {
if (curt.children[chars[index] - 'a'] == null) return false;
return search(chars, index + 1, curt.children[chars[index] - 'a']);
}
return false;
}
class TrieNode:
def __init__(self):
self.children = {}
self.isEnd = False
class WordDictionary:
def __init__(self):
"""
Initialize your data structure here.
"""
self.root = TrieNode()
def addWord(self, word: str) -> None:
"""
Adds a word into the data structure.
"""
curt = self.root
for char in word:
if char not in curt.children:
curt.children[char] = TrieNode()
curt = curt.children[char]
curt.isEnd = True
def search(self, word: str) -> bool:
"""
Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter.
"""
return self.dfs(0, word, self.root)
def dfs(self, i, word, curt):
if i == len(word):
return curt.isEnd
if word[i] != '.':
if word[i] not in curt.children:
return False
return self.dfs(i + 1, word, curt.children[word[i]])
else:
for key in curt.children:
if self.dfs(i + 1, word, curt.children[key]):
return True
return False
class TrieNode {
TrieNode[] children;
int index;
TrieNode() {
children = new TrieNode[27];
index = -1;
}
}
TrieNode root;
public List<String> removeSubfolders(String[] folder) {
root = new TrieNode();
for (int i = 0; i < folder.length; i++) {
TrieNode curt = root;
buildTrie(curt, folder[i], i);
}
List<String> result = new ArrayList<>();
BFS(root, folder, result);
return result;
}
private void BFS(TrieNode root, String[] folder, List<String> res) {
Queue<TrieNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
TrieNode curt = queue.poll();
if (curt.index != -1) {
res.add(folder[curt.index]);
}
for (int i = 0; i < 27; i++) {
if (curt.children[i] != null
&& !(i == 26 && curt.index != -1)) {
queue.offer(curt.children[i]);
}
}
}
}
private void buildTrie(TrieNode curt, String s, int index) {
for (char c : s.toCharArray()) {
int id = c == '/' ? 26 : c - 'a';
if (curt.children[id] == null) {
curt.children[id] = new TrieNode();
}
curt = curt.children[id];
}
curt.index = index;
}
class TrieNode {
TrieNode[] children;
String word;
TrieNode() {
children = new TrieNode[26];
}
}
TrieNode root = new TrieNode();
public List<String> findWords(char[][] board, String[] words) {
if (board == null || board.length == 0 || board[0].length == 0 || words.length == 0) {
return new ArrayList<>();
}
for (String w: words) {
buildTrie(w, root);
}
List<String> res = new ArrayList<>();
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
dfs(board, i, j, root, res);
}
}
return res;
}
int[][] dirs = {{1,0}, {-1, 0}, {0,1}, {0,-1}};
private void dfs(char[][] board, int x, int y, TrieNode curt, List<String> res) {
if (!inbound(board, x, y) || board[x][y] == '#') return;
int index = board[x][y] - 'a';
curt = curt.children[index];
if (curt == null) return;
if (curt.word != null) {
res.add(curt.word);
curt.word = null;
}
char c = board[x][y];
for (int[] d : dirs) {
board[x][y] = '#';
dfs(board, x + d[0], y + d[1], curt, res);
board[x][y] = c;
}
}
private void buildTrie(String w, TrieNode root) {
TrieNode curt = root;
for (char c : w.toCharArray()) {
int index = c - 'a';
if (curt.children[index] == null) curt.children[index] = new TrieNode();
curt = curt.children[index];
}
curt.word = w;
}
private boolean inbound(char[][] board, int x, int y) {
return x >= 0 && x < board.length && y >= 0 && y < board[0].length;
}
TrieNode root;
public List<List<String>> suggestedProducts(String[] products, String searchWord) {
root = new TrieNode();
Arrays.sort(products);
for (String product : products) {
buildTrie(root, product);
}
List<List<String>> results = new ArrayList<>();
char[] chars = searchWord.toCharArray();
int i = 0;
while (i < chars.length) {
int index = chars[i] - 'a';
if (root.children[index] == null) {
while (i++ < chars.length) {
results.add(new ArrayList<>());
}
} else {
results.add(new ArrayList<>(root.children[index].words));
root = root.children[index];
}
i++;
}
return results;
}
private void buildTrie(TrieNode curt, String w) {
char[] arr = w.toCharArray();
for (int i = 0; i < arr.length; i++) {
int index = arr[i] - 'a';
if (curt.children[index] == null) {
curt.children[index] = new TrieNode();
}
curt = curt.children[index];
if (curt.words.size() < 3) {
curt.words.add(w);
}
}
curt.isEnd = true;
}
class TrieNode {
TrieNode[] children;
List<String> words;
boolean isEnd;
TrieNode() {
children = new TrieNode[26];
words = new ArrayList<>();
}
}
public List<String> findAllConcatenatedWordsInADict(String[] words) {
List<String> res = new ArrayList<String>();
if (words == null || words.length == 0) {
return res;
}
TrieNode root = new TrieNode();
for (String w : words) {
addWord(w, root);
}
for (String w : words) {
if (search(w.toCharArray(), 0, root, 0)) {
res.add(w);
}
}
return res;
}
public boolean search(char[] chars, int index, TrieNode root, int count) {
if (index == chars.length) return count >= 2;
TrieNode curt = root;
for (int i = index; i < chars.length; i++) {
int id = chars[i] - 'a';
if (curt.children[id] == null) return false;
curt = curt.children[id];
if (curt.isEnd && search(chars, i + 1, root, count + 1)) {
return true;
}
}
return false;
}
public void addWord(String str, TrieNode root) {
char[] chars = str.toCharArray();
TrieNode cur = root;
for (char c : chars) {
if (cur.children[c - 'a'] == null) {
cur.children[c - 'a'] = new TrieNode();
}
cur = cur.children[c - 'a'];
}
cur.isEnd = true;
}
class TrieNode {
TrieNode[] children;
boolean isEnd;
public TrieNode() {
children = new TrieNode[26];
}
}
class TrieNode {
TrieNode[] children;
String word;
TrieNode() {
children = new TrieNode[26];
}
}
TrieNode root = new TrieNode();
public List<String> findWords(char[][] board, String[] words) {
if (board == null || board.length == 0 || board[0].length == 0 || words.length == 0) {
return new ArrayList<>();
}
for (String w: words) {
buildTrie(w, root);
}
List<String> res = new ArrayList<>();
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
dfs(board, i, j, root, res);
}
}
return res;
}
int[][] dirs = {{1,0}, {-1, 0}, {0,1}, {0,-1}};
private void dfs(char[][] board, int x, int y, TrieNode curt, List<String> res) {
if (!inbound(board, x, y) || board[x][y] == '#') return;
int index = board[x][y] - 'a';
if (curt.children[index] == null) return;
curt = curt.children[index];
if (curt.word != null) {
res.add(curt.word);
curt.word = null;
}
for (int[] dir : dirs) {
char c = board[x][y];
board[x][y] = '#';
dfs(board, x + dir[0], y + dir[1], curt, res);
board[x][y] = c;
}
}
private void buildTrie(String w, TrieNode root) {
TrieNode curt = root;
for (char c : w.toCharArray()) {
int index = c - 'a';
if (curt.children[index] == null) curt.children[index] = new TrieNode();
curt = curt.children[index];
}
curt.word = w;
}
private boolean inbound(char[][] board, int x, int y) {
return x >= 0 && x < board.length && y >= 0 && y < board[0].length;
}
TrieNode root;
String prefix;
public AutocompleteSystem(String[] sentences, int[] times) {
root = new TrieNode();
prefix = "";
for (int i = 0; i < sentences.length; i++) {
buildTrie(root, sentences[i], times[i]);
}
}
private void buildTrie(TrieNode curt, String s, int time) {
for (char c : s.toCharArray()) {
TrieNode next = curt.children.get(c);
if (next == null) {
next = new TrieNode();
curt.children.put(c, next);
}
curt = next;
curt.count.put(s, curt.count.getOrDefault(s, 0) + time);
}
curt.isEnd = true;
}
public List<String> input(char c) {
if (c == '#') { // add prefix to Trie and reset prefix
buildTrie(root, prefix, 1);
prefix = "";
return new ArrayList<>();
}
prefix = prefix + c;
TrieNode curt = root;
for (char cc: prefix.toCharArray()) {
if (curt.children.get(cc) == null) return new ArrayList<>();
curt = curt.children.get(cc);
}
return curt.getTop3();
}
class TrieNode {
Map<Character, TrieNode> children;
Map<String, Integer> count;
boolean isEnd;
TrieNode() {
this.children = new HashMap<>();
this.count = new HashMap<>();
this.isEnd = false;
}
public List<String> getTop3() {
List<String> res = new ArrayList<>();
PriorityQueue<Map.Entry<String, Integer>> pq
= new PriorityQueue<>(new Comparator<Map.Entry<String, Integer>>() {
@Override
public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
if (o1.getValue() == o2.getValue()) {
return o1.getKey().compareTo(o2.getKey());
}
return o2.getValue() - o1.getValue();
}
});
pq.addAll(count.entrySet());
for (int i = 0; i < 3 && !pq.isEmpty(); i++) {
res.add(pq.poll().getKey());
}
return res;
}
}
TrieNode root;
StringBuilder sb;
public StreamChecker(String[] words) {
root = new TrieNode();
for (String w : words) {
add(w.toCharArray());
}
sb = new StringBuilder();
}
public boolean query(char letter) {
sb.append(letter);
TrieNode curt = root;
for (int i = sb.length() - 1; i >= 0; i--) {
int index = sb.charAt(i) - 'a';
if (curt.children[index] == null) return false;
curt = curt.children[index];
if (curt != null && curt.isWord) return true;
}
return false;
}
class TrieNode {
TrieNode[] children;
boolean isWord;
TrieNode() {
children = new TrieNode[26];
isWord = false;
}
}
private void add(char[] chars) {
TrieNode curt = root;
for (int i = chars.length - 1; i >= 0; i--) {
int id = chars[i] - 'a';
if (curt.children[id] == null) curt.children[id] = new TrieNode();
curt = curt.children[id];
}
curt.isWord = true;
}
public int numMatchingSubseq(String S, String[] words) {
TrieNode root = new TrieNode();
buildTrie(S, root);
int count = 0;
Map<String, Integer> map = new HashMap<>();
for (String w : words) {
map.put(w, map.getOrDefault(w, 0) + 1);
}
for (String w : map.keySet()) {
if (dfs(root, w.toCharArray(), 0)) {
count += map.get(w);
}
}
return count;
}
private boolean dfs(TrieNode curt, char[] chars, int i) {
if (i == chars.length) {
return true;
}
int index = chars[i] - 'a';
if (curt.children[index] != null) {
return dfs(curt.children[index], chars, i + 1);
} else {
for (int k = 0; k < 26; k++) {
if (curt.children[k] != null && dfs(curt.children[k], chars, i)) {
return true;
}
}
}
return false;
}
private void buildTrie(String s, TrieNode curt) {
for (int i = 0; i < s.length(); i++) {
int index = s.charAt(i) - 'a';
if (curt.children[index] == null) {
curt.children[index] = new TrieNode();
}
curt = curt.children[index];
}
curt.isEnd = true;
}
class TrieNode {
TrieNode[] children;
boolean isEnd;
TrieNode() {
children = new TrieNode[26];
}
}
class Item {
String word;
int index;
public Item (String s, int i) {
word = s;
index = i;
}
}
public int numMatchingSubseq(String S, String[] words) {
Queue<Item>[] dict = new Queue[26];
for (int i = 0; i < dict.length; i++) {
dict[i] = new LinkedList<>();
}
for (String word :words) {
if (word.length() > 0) {
dict[word.charAt(0) - 'a'].add(new Item(word, 0));
}
}
int count = 0;
for (char c : S.toCharArray()) {
Queue<Item> queue = dict[c - 'a'];
int size = queue.size();
for (int i = 0; i < size; i++) {
Item top = queue.poll();
top.index++;
if (top.index == top.word.length()) {
count++;
} else {
dict[top.word.charAt(top.index) - 'a'].add(top);
}
}
}
return count;
}