Given many words
, words[i]
has weight i
.
Design a class WordFilter
that supports one function, WordFilter.f(String prefix, String suffix)
. It will return the word with given prefix
and suffix
with maximum weight. If no word exists, return -1.
Examples:
Input:
WordFilter(["apple"])
WordFilter.f("a", "e") // returns 0
WordFilter.f("b", "") // returns -1
Note:
words
has length in range[1, 15000]
.- For each test case, up to
words.length
queriesWordFilter.f
may be made. words[i]
has length in range[1, 10]
.prefix, suffix
have lengths in range[0, 10]
.words[i]
andprefix, suffix
queries consist of lowercase letters only.
解题思路:
这是一道查找前缀和后缀的题,问题在于如何将所有含有相同前缀的单词都集合到一起,这就需要构建trie树。因为是查找前缀和后缀,这里就用到一个小技巧,将所有可能的后缀就加到相应单词的前面,这样就可以转换成查找相应单词了。为了将后缀+前缀连接成的单词与某个单词中的相同子串区分开,在后缀和前缀之间+'{' , 因为'{'的ascall码比'z'大1 ; 所以不用与其他字符区分处理;
struct Node{
int w ;
vector<Node*> child = vector<Node*>(27 , NULL) ;
Node():w(-1) {}
Node(int weight):w(weight){}
};
class WordFilter {
public:
WordFilter(vector<string>& words)
{
root = new Node() ;
for(int i = 0 ; i < words.size() ; ++i)
{
string s = words[i] ;
string key = '{' + s ;
addtree(root , key , i) ;
for(int j = s.size() - 1 ; j >= 0 ; --j)
{
key = s[j] + key ;
addtree(root , key , i) ;
}
}
}
int f(string prefix, string suffix)
{
return search(suffix + '{' + prefix , root) ;
}
int search(string s , Node* root)
{
Node* cl ;
for(int i = 0 ; i < s.size() ; ++i)
{
cl = root->child[s[i] - 'a'] ;
if(cl) root = cl ;
else return -1 ;
}
return cl->w ;
}
void addtree(Node* root , string& s , int w)
{
Node* p = root ;
for(int i = 0 ; i < s.size() ; ++i )
{
if(p->child[s[i] - 'a'])
{
p = p->child[s[i] - 'a'] ;
p->w = max(w , p->w) ;
}
else
{
p->child[s[i] - 'a'] = new Node(w) ;
p = p->child[s[i] - 'a'] ;
}
}
}
private :
Node* root ;
};
/**
* Your WordFilter object will be instantiated and called as such:
* WordFilter* obj = new WordFilter(words);
* int param_1 = obj->f(prefix,suffix);
*/