字符流
此題主要是建立字典樹的思路有點難。
由於每次都要用到字符流的末尾,所以實際上是給定一個長字符串,判斷字典樹裏是否有單詞是它的後綴。
比如 字典樹{"bc","cd"}
,字符串"abc"
的後綴bc
字典裏出現。
如果是樸素想法的話,那應該每次去切割長的字符串,然後去字典樹裏查詢,這樣時間複雜度高達。
但是如果倒過來考慮,就很簡單了。
字典樹裏的單詞一開始就反向插入,帶查詢的字符串也是反向查詢,剛好滿足題目的要求去,時間複雜度。
class StreamChecker {
struct Node{
bool isEnd = false;
Node* children[26] = {0};
};
Node* root = new Node;
void insert(const string& s){
Node* p = root;
for(char c:s){
if(!p->children[c-'a']){
p->children[c-'a'] = new Node;
}
p = p->children[c-'a'];
}
p->isEnd = true;
}
bool ask(const string& s){
Node* p = root;
for(int i=s.size()-1;i>=0;i--){ //反向遍歷
char c = s[i];
if(!p->children[c-'a']){
return false;
}
p = p->children[c-'a'];
if(p->isEnd){
return true;
}
}
return false;
}
public:
string s = "";
StreamChecker(vector<string>& words) {
for(auto&s:words){
reverse(s.begin(),s.end());
insert(s);
}
}
bool query(char letter) {
s.push_back(letter); //如果是頭部插入的話,開銷很大
// s += letter ; 這也是可以的
return ask(s);
}
};
/**
* Your StreamChecker object will be instantiated and called as such:
* StreamChecker* obj = new StreamChecker(words);
* bool param_1 = obj->query(letter);
*/