Leetcode 745. 前缀和后缀搜索
题目
给定多个 words,words[i] 的权重为 i 。
设计一个类 WordFilter 实现函数WordFilter.f(String prefix, String suffix)。这个函数将返回具有前缀 prefix 和后缀suffix 的词的最大权重。如果没有这样的词,返回 -1。
测试样例:
输入:
WordFilter(["apple"])
WordFilter.f("a", "e") // 返回 0
WordFilter.f("b", "") // 返回 -1
注意:
- words的长度在[1, 15000]之间。
- 对于每个测试用例,最多会有words.length次对WordFilter.f的调用。
- words[i]的长度在[1, 10]之间。
- prefix, suffix的长度在[0, 10]之前。
- words[i]和prefix,suffix只包含小写字母。
题解
字典树
我们在构建字典树的同时就把所有可能的前后缀进行组合,其中后缀我们放到前面,前缀则采用完整的字符串即可。这样,我们在查找时,先判断后缀是否存在,再判断前缀是否存在,则dfs找符合要求的字符串的最大权值。需要注意的是,为了区分前后缀,我们需要用一个特殊的字符进行分割,这里我们采用了{,也就是z+1。详细过程见代码
代码
class WordFilter {
public:
struct Trim{
bool isWorld;
int value;
Trim* next[27];
Trim(){
for(int i=0; i<27; i++)
next[i] = 0;
isWorld = false;
}
};
Trim* root;
WordFilter(vector<string>& words) {
root = new Trim();
string append;
append = 'z'+1;
int n = words.size();
for(int i=0; i<n; i++){ //构建words[i]的字典树
string x;
for(int j=words[i].length(); j>=0; j--){ //获取每一种后缀,和字符串进行连接
x = words[i].substr(j) + append + words[i];
//cout<<x<<endl;
Trim* now = root;
for(int k=0; k<x.length(); k++){
if(now->next[x[k]-'a'] == NULL){
Trim* newN = new Trim();
now->next[x[k]-'a'] = newN;
}
now = now->next[x[k]-'a'];
}
now->isWorld = true;
now->value = i;
}
}
}
int ans=-1;
void dfs(Trim* now){ //查找符合要求的字符串的最大权值
//cout<<now->isWorld<<endl;
if(now->isWorld) ans = max(ans,now->value);
for(int i=0; i<26; i++){
if(now->next[i]!=NULL){
dfs(now->next[i]);
}
}
}
int f(string prefix, string suffix) {
Trim* now = root;
string append;
append = 'z'+1;
string src = suffix + append + prefix; //构造目标串,也就是后缀+分隔符+前缀
for(int i=0; i<src.size(); i++){ //是否有符合要求的目标串
//cout<<src[i]<<" ";
if(now->next[src[i]-'a'] == NULL) return -1;
now = now->next[src[i]-'a'];
}
ans = -1;
dfs(now);
return ans;
}
};
/**
* Your WordFilter object will be instantiated and called as such:
* WordFilter* obj = new WordFilter(words);
* int param_1 = obj->f(prefix,suffix);
*/
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/prefix-and-suffix-search
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。