在英语中,我们有一个叫做 词根(root) 的概念,可以词根后面添加其他一些词组成另一个较长的单词——我们称这个词为 继承词(successor)。例如,词根an,跟随着单词 other(其他),可以形成新的单词 another(另一个)。
现在,给定一个由许多词根组成的词典 dictionary 和一个用空格分隔单词形成的句子 sentence。你需要将句子中的所有继承词用词根替换掉。如果继承词有许多可以形成它的词根,则用最短的词根替换它。
你需要输出替换之后的句子。
示例 1:
输入:dictionary = ["cat","bat","rat"], sentence = "the cattle was rattled by the battery"
输出:"the cat was rat by the bat"
示例 2:
输入:dictionary = ["a","b","c"], sentence = "aadsfasf absbs bbab cadsfafs"
输出:"a a b c"
思路:前缀树
注意字符串的分割 和 查找前缀时if条件判断的顺序
class TrieNode
{
private:
bool isEnd;
vector<TrieNode*> next;
public:
TrieNode()
{
isEnd=false;
next.resize(26,nullptr);
}
void insert(string& word)// 插入单词
{
TrieNode* root=this;
for(char c:word)
{
if(root->next[c-'a']==nullptr)
root->next[c-'a']=new TrieNode();
root=root->next[c-'a'];
}
root->isEnd=true;
}
string prefix(string& word)// 查找前缀
{
TrieNode* root=this;
string res;
for(char c:word)
{
if(root->isEnd)//一旦到达某一个前缀的尾部,就立即返回这个前缀(最短的前缀)
{
return res;
}
if(root->next[c-'a']==nullptr)//在没有到达前缀尾部时就出现空缺的情况,说明它就没有词根,返回原词
{
return word;
}
res+=c;
root=root->next[c-'a'];
}
return res;//能走出循环,说明res==word
}
};
class Solution
{
public:
string replaceWords(vector<string>& dict, string s)
{
TrieNode* root=new TrieNode();
for(string trie:dict)
root->insert(trie);
string res;
s+=' ';
for(int i=0;i<s.size();i++)
{
int index=s.find(' ',i);
string word=s.substr(i,index-i);
res+=root->prefix(word)+' ';
i=index;
}
delete(root);
res=res.substr(0,res.size()-1);
return res;
}
};