Description:
Given multiple words, the weight of words[i] is I.
Design a class WordFilter to implement the function WordFilter.f(String prefix, String suffix). This function returns the maximum weight of the word with prefix prefix and suffix suffix suffix. If there is no such word, return - 1.
Example:
input: WordFilter(["apple"]) WordFilter.f("a", "e") // Return to 0 WordFilter.f("b", "") // Return to -1
Be careful:
The length of words is between [1, 15000]. For each test case, there will be a maximum of words.length calls to WordFilter.f. The length of words[i] is between [1,10]. prefix, suffix is before [0, 10]. words[i] and prefix, suffix contains only lowercase letters.
Thought analysis:
This kind of word search generally uses prefix tree to process, that is, through the structure of prefix tree to store all word sets, reducing the purpose of repeated search when searching words. About prefix tree and its application Implementation and application of prefix tree
Step one: build a tree. Convert vector < string > & words to prefix tree Step 2: first, determine whether prefix prefix exists Step 3: in the subtree starting with prefixRoot, the suffix of the search word is the maximum weight of suffix
//Program representation of prefix tree class TrieNode { public: bool isWord;//Whether the current node ends with a word int weight = 0;//Weight only makes sense when isWord == true vector<TrieNode*> children; TrieNode() : isWord(false), children(26, nullptr), weight(0) {} ~TrieNode() { for (TrieNode* child : children) if (child) delete child; } }; class WordFilter { public: TrieNode *trieRoot;//Constructed word prefix tree //Add a word and its weight to the tree void addWord(string &word, int weight) { TrieNode *ptr = trieRoot;//Scan the tree and insert word for (auto ch : word) { if (ptr->children[ch - 'a'] == NULL) { ptr->children[ch - 'a'] = new TrieNode(); } ptr = ptr->children[ch - 'a']; } ptr->isWord = true;//Mark as word ptr->weight = weight;//Record weight } //Search the prefix tree of a word for the existence of prefix, and return the node corresponding to the prefix TrieNode *myFindPrefix(string &prefix){ TrieNode *ptr = trieRoot;//Scan the tree for (auto ch : prefix){ if (ptr->children[ch - 'a'] == NULL) { //Null if prefix does not exist return NULL; } else{ ptr = ptr->children[ch - 'a']; } } return ptr;//Otherwise, return the node address at the end of prefix prefix } //In the subtree starting with prefixRoot, the suffix of the search word is the maximum weight of suffix void myFind(TrieNode *prefixRoot, string word, string &suffix, int &maxRes){ if (prefixRoot->isWord && word.substr(word.size() - suffix.size()) == suffix){ //If prefixRoot is the end of a word at this time, and the suffix of the word is suffix maxRes = max(maxRes, prefixRoot->weight); } int wordSize = word.size(); word += 'a'; //Attempt to search 26 non empty child nodes of prefixRoot for (int index = 0; index < 26; ++index){ if (prefixRoot->children[index]){//Not empty word[wordSize] = 'a' + index; myFind(prefixRoot->children[index], word, suffix, maxRes); } } } WordFilter(vector<string>& words) { //Vector < string > & words to prefix tree trieRoot = new TrieNode(); int wordsSize = words.size(); for (int index = 0; index < wordsSize; ++index){ addWord(words[index], index); } } int f(string prefix, string suffix) { //The first step is to determine whether prefix prefix exists TrieNode *prefixRoot = myFindPrefix(prefix); if (prefixRoot == NULL){ return -1; } //In the subtree starting with prefixRoot, the suffix of the search word is the maximum weight of suffix int maxRes = -1; myFind(prefixRoot, prefix, suffix, maxRes); return maxRes; } }; /** * Your WordFilter object will be instantiated and called as such: * WordFilter* obj = new WordFilter(words); * int param_1 = obj->f(prefix,suffix); */