LeetCode 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 <= dictionaryi.length <= 100

dictionaryi 仅由小写字母组成。

1 <= sentence.length <= 106^66

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

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

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

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

sentence 没有前导或尾随空格。

我们可以使用字典树,先把所有词根前缀存入字典树,然后对sentence中的每个单词查询是否在字典树中,如果在,就只保留前缀:

cpp 复制代码
class Node {
public:
    vector<Node *> next = vector<Node *>(26, nullptr);
    bool isEnd = false;
};

class Solution {
public:
    string replaceWords(vector<string>& dictionary, string sentence) {
        Node *root = new Node();
        // 存入字典树
        for (string s : dictionary) {
            Node *curNode = root;
            for (char c : s) {
                if (curNode->next[c - 'a'] == nullptr) {
                    curNode->next[c - 'a'] = new Node();
                }
                curNode = curNode->next[c - 'a'];
            }
            curNode->isEnd = true;
        }

        string ans;
        for (int i = 0; i < sentence.size(); ++i) {
            Node *curNode = root;
            while (i < sentence.size() && sentence[i] != ' ') {
                char c = sentence[i];
                // 逐字符字典树查找
                if (curNode->next[c - 'a'] != nullptr) {
                    ans += c;
                    curNode = curNode->next[c - 'a'];

                    // 如果是一个前缀
                    if (curNode->isEnd) {
                        break;
                    }
                } else {
                    break;
                }
                ++i;
            }

            while (i < sentence.size() && sentence[i] != ' ') {
                // 如果没找到词根前缀,就把单词完整放入答案
                if (!curNode->isEnd) {
                    ans += sentence[i];
                }

                ++i;
            }

            if (i < sentence.size() && sentence[i] == ' ') {
                ans += ' ';
            }
        }

        return ans;
    }
};

如果词缀中有n个字母,sentence的长度为m,则此算法时间复杂度为O(n+m),空间复杂度为O(n)。

相关推荐
ychqsq6 小时前
201.春风
经验分享·职场和发展
小蒋学算法6 小时前
算法-交替删除操作后最后剩下的整数-跟着灵茶山艾府学算法
数据结构·算法
荆棘鸟智能7 小时前
林业遥感长势评估怎么做?从NDVI时序分析到LiDAR蓄积量回归
人工智能·算法·智慧林业
hhb_6188 小时前
AIRAGDebug:一键定位RAG链路异常
人工智能·python·算法
泡沫_花火8 小时前
大模型开发相关岗位面试资料(含算法)
语言模型·自然语言处理·面试·职场和发展
朝朝辞暮i8 小时前
C++ 第 6 课:switch —— 多状态选择
开发语言·c++·算法
苏打豆8 小时前
Pinocchio源码阅读——刚体运动物理量空间变换及求导
c++·线性代数·算法·矩阵·机器人
FluxArt9 小时前
GPT Image 2.5 中文提示词教程:Flux Art 可复用模板
前端·gpt·算法
思麟呀9 小时前
位运算:从一个整数到一个集合
c语言·数据结构·c++·算法
阜阳山君GEO9 小时前
豆包 SEED 新版本 GEO 优化:信源金字塔、打分体系与避坑落地指南
人工智能·算法