Welcome to Subscribe On Youtube
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.
Solutions
-
class Trie { Trie[] children = new Trie[26]; boolean isEnd = false; public void insert(String w) { Trie node = this; for (int i = w.length() - 1; i >= 0; --i) { int idx = w.charAt(i) - 'a'; if (node.children[idx] == null) { node.children[idx] = new Trie(); } node = node.children[idx]; } node.isEnd = true; } public boolean query(StringBuilder s) { Trie node = this; for (int i = s.length() - 1; i >= 0; --i) { int idx = s.charAt(i) - 'a'; if (node.children[idx] == null) { return false; } node = node.children[idx]; if (node.isEnd) { return true; } } return false; } } class StreamChecker { private StringBuilder sb = new StringBuilder(); private Trie trie = new Trie(); public StreamChecker(String[] words) { for (String w : words) { trie.insert(w); } } public boolean query(char letter) { sb.append(letter); return trie.query(sb); } } /** * Your StreamChecker object will be instantiated and called as such: * StreamChecker obj = new StreamChecker(words); * boolean param_1 = obj.query(letter); */
-
class Trie { public: vector<Trie*> children; bool isEnd; Trie() : children(26) , isEnd(false) {} void insert(string& w) { Trie* node = this; reverse(w.begin(), w.end()); for (char& c : w) { int idx = c - 'a'; if (!node->children[idx]) { node->children[idx] = new Trie(); } node = node->children[idx]; } node->isEnd = true; } bool search(string& w) { Trie* node = this; for (int i = w.size() - 1; ~i; --i) { int idx = w[i] - 'a'; if (!node->children[idx]) { return false; } node = node->children[idx]; if (node->isEnd) { return true; } } return false; } }; class StreamChecker { public: Trie* trie = new Trie(); string s; StreamChecker(vector<string>& words) { for (auto&& w : words) { trie->insert(w); } } bool query(char letter) { s += letter; return trie->search(s); } }; /** * Your StreamChecker object will be instantiated and called as such: * StreamChecker* obj = new StreamChecker(words); * bool param_1 = obj->query(letter); */
-
class Trie: def __init__(self): self.children = [None] * 26 self.is_end = False def insert(self, w: str): node = self for c in w[::-1]: idx = ord(c) - ord('a') if node.children[idx] is None: node.children[idx] = Trie() node = node.children[idx] node.is_end = True def search(self, w: List[str]) -> bool: node = self for c in w[::-1]: idx = ord(c) - ord('a') if node.children[idx] is None: return False node = node.children[idx] if node.is_end: return True return False class StreamChecker: def __init__(self, words: List[str]): self.trie = Trie() self.cs = [] self.limit = 201 for w in words: self.trie.insert(w) def query(self, letter: str) -> bool: self.cs.append(letter) return self.trie.search(self.cs[-self.limit :]) # Your StreamChecker object will be instantiated and called as such: # obj = StreamChecker(words) # param_1 = obj.query(letter)
-
type Trie struct { children [26]*Trie isEnd bool } func newTrie() Trie { return Trie{} } func (this *Trie) Insert(word string) { node := this for i := len(word) - 1; i >= 0; i-- { idx := word[i] - 'a' if node.children[idx] == nil { node.children[idx] = &Trie{} } node = node.children[idx] } node.isEnd = true } func (this *Trie) Search(word []byte) bool { node := this for i := len(word) - 1; i >= 0; i-- { idx := word[i] - 'a' if node.children[idx] == nil { return false } node = node.children[idx] if node.isEnd { return true } } return false } type StreamChecker struct { trie Trie s []byte } func Constructor(words []string) StreamChecker { trie := newTrie() for _, w := range words { trie.Insert(w) } return StreamChecker{trie, []byte{} } } func (this *StreamChecker) Query(letter byte) bool { this.s = append(this.s, letter) return this.trie.Search(this.s) } /** * Your StreamChecker object will be instantiated and called as such: * obj := Constructor(words); * param_1 := obj.Query(letter); */