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 <= 20001 <= words[i].length <= 200words[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 queryWe'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. |