【数据结构-Trie树】力扣648. 单词替换

在英语中,我们有一个叫做 词根(root) 的概念,可以词根 后面 添加其他一些词组成另一个较长的单词------我们称这个词为 衍生词 (derivative)。例如,词根 help,跟随着 继承词 "ful",可以形成新的单词 "helpful"。

现在,给定一个由许多 词根 组成的词典 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"

提示:

1 <= dictionary.length <= 1000

1 <= dictionary[i].length <= 100

dictionary[i] 仅由小写字母组成。

1 <= sentence.length <= 106

sentence 仅由小写字母和空格组成。

sentence 中单词的总量在范围 [1, 1000] 内。

sentence 中每个单词的长度在范围 [1, 1000] 内。

sentence 中单词之间由一个空格隔开。

sentence 没有前导或尾随空格。

字典树

csharp 复制代码
class Solution {
private:
    struct trie{
        vector<trie*> children;
        bool isWord;
        trie(): children(26, nullptr), isWord(false){};
    };
    trie* root;

    vector<string> split(const string& sentence, char del){
        vector<string> result;
        string word;
        for(char c : sentence){
            if(c == del){
                if(!word.empty()){
                    result.push_back(word);
                    word.clear();
                }
            }
            else{
                word += c;
            }
        }
        if(!word.empty()){
            result.push_back(word);
        }
        return result;
    }

public:
    Solution(){
        root = new trie();
    }

    string replaceWords(vector<string>& dictionary, string sentence) {
        for(string word : dictionary){
            add(word);
        }

        vector<string> words = split(sentence, ' ');
        vector<string> ans;

        for(string word : words){
            ans.push_back(findPrefix(word));
        }
        
        string res;
        for(int i = 0; i < ans.size() - 1; i++){
            res += ans[i];
            res += ' ';
        }
        res += ans[ans.size() - 1];
        return res;
    }

    void add(string word){
        trie* node = root;
        for(char ch : word){
            ch -= 'a';
            if(node->children[ch] == nullptr){
                node->children[ch] = new trie();
            }
            node = node->children[ch];
        }
        node->isWord = true;
    }

    string findPrefix(string word){
        string prefix;
        trie* node = root;
        for(char ch : word){
            ch -= 'a';
            if(node->children[ch] == nullptr){
                break;
            }
            prefix += ch + 'a';
            node = node->children[ch];
            if(node->isWord){
                return prefix;
            }
        }
        return word;
    }
};

这道题我们可以先将dictionary里的词根用Trie树来储存,并且我们用一个布尔值isWord来判断某一个节点是否是一个词根的结尾。

接下来我们自定义一个split函数用来将sentence的单词储存到vector的words中,接下来我们定义一个findPrefix函数,将words中的每一个word在字典树中进行查找,看有没有词根,如果有的话就返回词根,否则返回word自身。这样子我们的ans中储存的就是替换过的单词。

由于我们最后要返回的是一个句子,那么我们就将ans中的单词中插入空格,储存到res中,最后返回res即可。

相关推荐
爱coding的橙子1 小时前
每日算法刷题Day24 6.6:leetcode二分答案2道题,用时1h(下次计时20min没写出来直接看题解,节省时间)
java·算法·leetcode
慢慢慢时光1 小时前
leetcode sql50题
算法·leetcode·职场和发展
pay顿1 小时前
力扣LeetBook数组和字符串--二维数组
算法·leetcode
The Future is mine1 小时前
在.NET Core控制器中获取AJAX传递的Body参数
c#·.netcore
岁忧1 小时前
(nice!!!)(LeetCode每日一题)2434. 使用机器人打印字典序最小的字符串(贪心+栈)
java·c++·算法·leetcode·职场和发展·go
Tisfy1 小时前
LeetCode 2434.使用机器人打印字典序最小的字符串:贪心(栈)——清晰题解
leetcode·机器人·字符串·题解·贪心·
dying_man1 小时前
LeetCode--18.四数之和
算法·leetcode
无敌的小笼包1 小时前
第四讲:类和对象(下)
数据结构·c++
Eiceblue2 小时前
C# 快速检测 PDF 是否加密,并验证正确密码
开发语言·pdf·c#·visual studio
FL16238631292 小时前
C#报错 iText.Kernel.Exceptions.PdfException: ‘Unknown PdfException
开发语言·c#