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 array words
.boolean query(char letter)
Accepts a new character from the stream and returns true
if any non-empty suffix from the stream forms a word that is in words
.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.4 * 104
calls will be made to query.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
We want to see if characters from a stream form a word from a given dictionary. The brute force method simply checks every possible prefix of the stream against all words in the dictionary.
Here's how the algorithm would work step-by-step:
def stream_of_characters_brute_force(words):
streamed_characters = []
def query(character):
streamed_characters.append(character)
for start_index in range(len(streamed_characters)):
# Iterate through possible start indices in the stream
current_string = "".join(streamed_characters[start_index:])
# Check if current_string matches any word
if current_string in words:
return True
#If no match, we have to return False
return False
return query
We're given a stream of characters and need to quickly check if any recent sequence of characters matches a given set of words. The trick is to build a specialized data structure that efficiently stores the words we're looking for, enabling fast prefix matching as new characters arrive.
Here's how the algorithm would work step-by-step:
class StreamChecker:
def __init__(self, words):
self.trie = { }
self.words = words
for word in words:
current_node = self.trie
for char in reversed(word):
if char not in current_node:
current_node[char] = { }
current_node = current_node[char]
current_node['#'] = True
self.current_string = ""
def query(self, letter):
self.current_string += letter
current_node = self.trie
for char in reversed(self.current_string):
if char not in current_node:
return False
current_node = current_node[char]
# Check for complete word.
if '#' in current_node:
return True
return False
# Your StreamChecker object will be instantiated and called as such:
# stream_checker = StreamChecker(words)
# result = stream_checker.query(letter)
Case | How to Handle |
---|---|
words is null or empty | Initialize the data structure with an empty Trie and return false for all queries. |
words contains an empty string | Treat the empty string as a valid word in the Trie. |
words contains duplicate words | The Trie construction will naturally handle duplicates without issues. |
Stream contains only a single character which matches a word | Should correctly return true as the single character is a word suffix. |
Long stream where no suffix matches any word in the 'words' array | Consistently return false, demonstrating the algorithm avoids false positives. |
A word in 'words' is a prefix of another word in 'words' | Trie should correctly identify both words as valid suffixes if they appear in the stream. |
Maximum length of the stream or the words is extremely large, exceeding available memory | The Trie data structure's memory consumption should be carefully considered to prevent memory overflow, perhaps by limiting the max length of words in words. |
The character stream is extremely long and the prefix is a substring of a word. This substring does not represent a valid word until the stream ends with the remainder of the word. | The Trie correctly identifies valid words when they are suffixes of the stream. |