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)。

相关推荐
辰烨chenye4 分钟前
LeetCode Hot 100 题解 · 普通数组篇
算法·leetcode·职场和发展
hqyjzsb3 小时前
零 AI 项目经验,学 Python 转型 AI 的正确顺序是什么?
开发语言·人工智能·python·算法·职场和发展·数据挖掘·数据分析
辰烨chenye3 小时前
LeetCode Hot 100 题解 · 二分篇
java·算法·leetcode
微功夫信息技术3 小时前
分层多智能体强化学习驱动的非急救转运公平 - 效率统一调度系统研究与实践
人工智能·学习·算法·动态规划
sanjiaomao3334 小时前
从论文公式到Python实现:用单元测试校验滑动平均算法
python·算法·单元测试
乐迪信息4 小时前
如何通过AI防爆摄像机精准判断船舶超速?
大数据·人工智能·算法·安全·目标跟踪
Interview Aid1125 小时前
Walmart Global Tech SDE 三轮面经|基础、并发、压力面
面试·职场和发展
大圣编蚕5 小时前
Java ByteArrayInputStream 详解:从入门到实战
java·开发语言·算法
小玮看世界6 小时前
[Python]OD算法在OD实际运用转化参考清单
开发语言·python·算法
黎阳之光6 小时前
数字孪生赋能全域水网,实现水资源管控与节水降碳双向提升
人工智能·物联网·算法·安全·数字孪生