leetcode 1032. Stream of Characters
题意:如果你稍微了解关于大数据/视频/音频流(Stream)处理的背景的话,你会觉得这道题非常棒。简单介绍下流处理,举个简单的例子,你在Youtobe上观看电影的时候不需要事先下载整个电影文件,而是进行缓存加载,来一点播放一点。前端视频代码需要对最近收到的视频文件进行检测,就要用到这个StreamChecker。
在这道题中,会大量进行Query,所以查询必须用Tri树的数据结构进行优化,在构造函数中做这件事。
query的描述我看了好久才明白什么意思,
- 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.
它指的是当收到一个letter的时候,查看最近收到的letter流的末尾是不是存在指定的单词,例如收到query('a'), query('b'), query('c')之后,letter流就是"abc", 我们只需要检测["c","bc","abc"]中是否有指定单词。
思路:简单字典树。
代码:
struct Node
{int next[500010][26], fail[500010], end[500010];int root, L;int newnode(){for (int i = 0; i < 26; i++)next[L][i] = -1;end[L++] = 0;return L - 1;}void insert(const char* buf){int len = strlen(buf);int now = root;for (int i = len-1; i >= 0; i--){if (next[now][buf[i] - 'a'] == -1)next[now][buf[i] - 'a'] = newnode();now = next[now][buf[i] - 'a'];}end[now]++;}void init(){L = 0;root = newnode();}
};class StreamChecker {
public:StreamChecker(vector<string>& words) {Tri.init();for (int i = 0; i < words.size(); i++)Tri.insert(words[i].c_str());}bool query(char letter) {s += letter;int now = Tri.root;for (int i = s.length() - 1; i >= 0; i--){int next = Tri.next[now][s[i] - 'a'];if (next == -1) break;now = next;if (Tri.end[now] != 0) return true;}return false;}string s;Node Tri;
};