目录

0648:单词替换(★)

力扣第 648 题

题目

在英语中,我们有一个叫做 词根(root) 的概念,可以词根 后面 添加其他一些词组成另一个较长的单词——我们称这个词为 继承词 (successor)。例如,词根 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 没有前导或尾随空格。

分析

容易想到用前缀树,先将词根插入,并在末尾用 ‘#’ 标记。 再对句子的每个单词搜索最短词根,遍历前缀树找到第一个 ‘#’ 标记即可。

解答

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
def replaceWords(self, dictionary: List[str], sentence: str) -> str:
    def find(word):
        p = trie
        for i, char in enumerate(word):
            if char not in p:
                return word
            p = p[char]
            if '#' in p:
                return word[:i+1]
        return word

    T = lambda: defaultdict(T)
    trie = T()
    for prefix in dictionary:
        reduce(dict.__getitem__, prefix, trie)['#'] = {}
    return ' '.join(find(word) for word in sentence.split())

72 ms