一.问题描述
mplement the StreamChecker
class as follows:
StreamChecker(words)
: Constructor, init the data structure with the given words.query(letter)
: returns true if and only if for somek >= 1
, the lastk
characters queried (in order from oldest to newest, including this letter just queried) spell one of the words in the given list.
Example:
StreamChecker streamChecker = new StreamChecker(["cd","f","kl"]); // init the dictionary. 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
Note:
1 <= words.length <= 2000
1 <= words[i].length <= 2000
- Words will only consist of lowercase English letters.
- Queries will only consist of lowercase English letters.
- The number of queries is at most 40000.
二.解题思路
最简单的就是,把所有word存在集合,集合查找操作相当于O(1),然后对输入流的每个后缀进行匹配,假设最后输入流的后缀最大长度是W,有K个查找,算法的时间复杂度就是O(KW),可以看到W的最大长度可以到4万,实现之后大概率超时,结果果然超时。
高效方法就是Trie 树,前缀树,(可以查一下Trie树是什么),将所有word以trie树的形式保存,然后根据输入流,从根节点进行搜索,最差的效能也是O(KW),不过大部分情况我们都不会遇到最差的情况,最长情况类似这样:输入流'aaaaaa',最后的树'baaaaa',一直查到最后一个才终止。
放上两种实现。
更多leetcode算法题解法请关注我的专栏leetcode算法从零到结束或关注我
欢迎大家一起套路一起刷题一起ac
三.源码
import string
class StreamChecker:
#TLE version, time limit excess
def __init__(self, words: List[str]):
self.words=set(words)
self.pre=''
def query(self, letter: str) -> bool:
self.pre=self.pre+letter
for i in range(0,len(self.pre)):
if self.pre[-i-1:] in self.words:
return True
return False
class StreamChecker:
# Trie version
def __init__(self, words: List[str]):
self.Trie={}
for word in words:
curnode=self.Trie
word=word[::-1]
for ch in word:
if ch not in curnode:
curnode[ch]={}
curnode=curnode[ch]
curnode['#']=1 # '#' means the end of a word
self.pre=''
def query(self, letter: str) -> bool:
self.pre=self.pre+letter
curnode=self.Trie
for i in range(0,len(self.pre)):
if self.pre[-i-1] not in curnode:
break
curnode=curnode[self.pre[-i-1]]
if '#' in curnode:
return True
return False