Design a special dictionary which has some words and allows you to search the words in it by a prefix and a suffix.
Implement the WordFilter
class:
WordFilter(string[] words)
Initializes the object with thewords
in the dictionary.f(string prefix, string suffix)
Returns the index of the word in the dictionary which has the prefixprefix
and the suffixsuffix
. If there is more than one valid index, return the largest of them. If there is no such word in the dictionary, return-1
.
Example 1:
Input ["WordFilter", "f"] [[["apple"]], ["a", "e"]] Output [null, 0] Explanation WordFilter wordFilter = new WordFilter(["apple"]); wordFilter.f("a", "e"); // return 0, because the word at index 0 has prefix = "a" and suffix = 'e".
Constraints:
1 <= words.length <= 15000
1 <= words[i].length <= 10
1 <= prefix.length, suffix.length <= 10
words[i]
,prefix
andsuffix
consist of lower-case English letters only.- At most
15000
calls will be made to the functionf
.
Related Topics:
Trie
Similar Questions:
// OJ: https://leetcode.com/problems/prefix-and-suffix-search/
// Author: github.com/lzl124631x
// Time:
// * WordFilter: O(WL)
// * f: O(L + W)
// Space: O(WL) where W is `words` length and L is max word length.
struct TrieNode {
TrieNode *next[26] = {};
vector<int> index;
};
class WordFilter {
TrieNode prefixRoot, suffixRoot;
void addWord(TrieNode *node, string &w, int i) {
for (char c : w) {
if (!node->next[c - 'a']) node->next[c - 'a'] = new TrieNode();
node = node->next[c - 'a'];
node->index.push_back(i);
}
}
vector<int> getIndexes(TrieNode *node, string &w) {
for (char c : w) {
node = node->next[c - 'a'];
if (!node) return {};
}
return node->index;
}
public:
WordFilter(vector<string>& words) {
for (int i = 0; i < words.size(); ++i) {
auto &w = words[i];
addWord(&prefixRoot, w, i);
reverse(begin(w), end(w));
addWord(&suffixRoot, w, i);
}
}
int f(string prefix, string suffix) {
reverse(begin(suffix), end(suffix));
auto p = getIndexes(&prefixRoot, prefix), s = getIndexes(&suffixRoot, suffix);
for (int i = p.size() - 1, j = s.size() - 1; i >= 0 && j >= 0; ) {
if (p[i] == s[j]) return p[i];
if (p[i] < s[j]) --j;
else --i;
}
return -1;
}
};