648. 单词替换
在英语中,我们有一个叫做 词根(root) 的概念,可以词根后面添加其他一些词组成另一个较长的单词——我们称这个词为 继承词(successor)。例如,词根an,跟随着单词 other(其他),可以形成新的单词 another(另一个)。
现在,给定一个由许多词根组成的词典 dictionary 和一个用空格分隔单词形成的句子 sentence。你需要将句子中的所有继承词用词根替换掉。如果继承词有许多可以形成它的词根,则用最短的词根替换它。
你需要输出替换之后的句子。
输入:dictionary = ["cat","bat","rat"], sentence = "the cattle was rattled by the battery"
输出:"the cat was rat by the bat"
输入:dictionary = ["a","b","c"], sentence = "aadsfasf absbs bbab cadsfafs"
输出:"a a b c"
1 <= dictionary.length <= 1000
1 <= dictionary[i].length <= 100
dictionary[i] 仅由小写字母组成。
1 <= sentence.length <= 10^6
sentence 仅由小写字母和空格组成。
sentence 中单词的总量在范围 [1, 1000] 内。
sentence 中每个单词的长度在范围 [1, 1000] 内。
sentence 中单词之间由一个空格隔开。
sentence 没有前导或尾随空格。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/replace-words
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思想就是讲词根构成一个前缀树,然后遍历每一个单词,找到前缀,再返回
因为要求最短前缀,所以给前缀树加了一个成员 isEnd指示某个前缀结束
struct TrieNode
{
bool isEnd;
unordered_map next;
};
class RootTree {
public:
TrieNode*root;
/** Initialize your data structure here. */
RootTree() {
root = new TrieNode();
root->isEnd = false;
}
void insert(string key) {
TrieNode* p = root;
for (int i = 0; i < key.length(); i++)
{
if ((p->next).count(key[i]) <= 0)
{
(p->next).insert(make_pair(key[i], new TrieNode()));
}
p = (p->next)[key[i]];
}
p->isEnd = true;
}
string findx(string &word)
{
TrieNode*p = root;
if ((p->next).count(word[0]) <= 0) return word;
string ans = word;
for (int i = 0; i < word.length(); ++i)
{
if ((p->next).count(word[i]) > 0)
{
p = (p->next)[word[i]];
if (p->isEnd)
{
ans = word.substr(0, i + 1);
break;
}
}
else
{
break;
}
}
return ans;
}
};
class Solution {
public:
string replaceWords(vector& dictionary, string sentence) {
//将词根插入到前缀树中
RootTree roottree;
for (int i = 0; i < dictionary.size(); ++i)
{
roottree.insert(dictionary[i]);
}
stringstream ss(sentence);
string w;
string ans = "";
while (ss >> w)
{
string temp = roottree.findx(w);
ans = ans + temp + " ";
}
ans.pop_back();
return ans;
}
};