1032. Stream of Characters
Description
Design an algorithm that accepts a stream of characters and checks if a suffix of these characters is a string of a given array of strings words
.
For example, if words = ["abc", "xyz"]
and the stream added the four characters (one by one) 'a'
, 'x'
, 'y'
, and 'z'
, your algorithm should detect that the suffix "xyz"
of the characters "axyz"
matches "xyz"
from words
.
Implement the StreamChecker
class:
StreamChecker(String[] words)
Initializes the object with the strings arraywords
.boolean query(char letter)
Accepts a new character from the stream and returnstrue
if any non-empty suffix from the stream forms a word that is inwords
.
Example 1:
Input ["StreamChecker", "query", "query", "query", "query", "query", "query", "query", "query", "query", "query", "query", "query"] [[["cd", "f", "kl"]], ["a"], ["b"], ["c"], ["d"], ["e"], ["f"], ["g"], ["h"], ["i"], ["j"], ["k"], ["l"]] Output [null, false, false, false, true, false, true, false, false, false, false, false, true] Explanation StreamChecker streamChecker = new StreamChecker(["cd", "f", "kl"]); streamChecker.query("a"); // return False streamChecker.query("b"); // return False streamChecker.query("c"); // return False streamChecker.query("d"); // return True, because 'cd' is in the wordlist streamChecker.query("e"); // return False streamChecker.query("f"); // return True, because 'f' is in the wordlist streamChecker.query("g"); // return False streamChecker.query("h"); // return False streamChecker.query("i"); // return False streamChecker.query("j"); // return False streamChecker.query("k"); // return False streamChecker.query("l"); // return True, because 'kl' is in the wordlist
Constraints:
1 <= words.length <= 2000
1 <= words[i].length <= 200
words[i]
consists of lowercase English letters.letter
is a lowercase English letter.- At most
4 * 104
calls will be made to query.
Solution
stream-of-characters.py
# ----------------------------------- Trie -----------------------------------
class Trie:
# https://github.com/cheran-senthil/PyRival/blob/master/pyrival/data_structures/Trie.py
def __init__(self, *words):
self.root = dict()
for word in words:
self.add(word)
def add(self, word):
current_dict = self.root
for letter in word:
current_dict = current_dict.setdefault(letter, dict())
current_dict["_end_"] = True
def __contains__(self, word):
exist = False
current_dict = self.root
for letter in word:
if letter not in current_dict:
break
current_dict = current_dict[letter]
exist |= "_end_" in current_dict
return exist
def delete(self, word, prune=False):
current_dict = self.root
nodes = [current_dict]
objects = []
for letter in word:
current_dict = current_dict[letter]
nodes.append(current_dict)
objects.append(current_dict)
del current_dict["_end_"]
if prune:
# https://leetcode.com/problems/maximum-genetic-difference-query/discuss/1344900/
for c, obj in zip(word[::-1], objects[:-1][::-1]):
if not obj[c]:
del obj[c]
else:
break
# assert word not in self # confirm that the number has been removed
class StreamChecker:
def __init__(self, words: List[str]):
self.trie = Trie()
for word in words:
self.trie.add(word[::-1])
self.curr = ""
def query(self, letter: str) -> bool:
self.curr = letter + self.curr
return self.curr in self.trie
# Your StreamChecker object will be instantiated and called as such:
# obj = StreamChecker(words)
# param_1 = obj.query(letter)