Leetcode 648 单词替换

一、题目

  英语中有一个叫做词根(root)的概念,我们可在词根后面添加其他一些词,组成另一个较长的单词——即继承词(successor)。例如,词根an跟随着单词other,可以形成新的单词another。

  现给定一个由许多词根组成的词典dictionary和一个用空格分隔单词形成的句子sentence。需将句子中的所有继承词用词根替换掉,若继承词有许多可以形成它的词根,则用最短的词根替换它。

  你需要输出替换之后的句子。

  示例 1:

    输入:dictionary = ["cat","bat","rat"], sentence = "the cattle was rattled by the battery"
    输出:"the cat was rat by the bat"

二、解法

  本题有两种解法,分别是:

    1)基于哈希表的朴素查找法

    2)基于前缀树的最短前缀匹配解法

  解法1的思路很直观,即将dictionary中所有的单词放在Hash Table中,然后依次匹配sentence中的每个单词。在匹配时,从每个单词中自左向右滑动窗口取其前缀,然后再Hash Table中进行查找,取最短的即可。

class Solution:
    def replaceWords(self, dictionary: List[str], sentence: str) -> str:
        dictionarySet = set(dictionary)
        words = sentence.split(' ')
        for i, word in enumerate(words):
            # find shortest prefix of the word brutely
            for j in range(1, len(words) + 1):
                if word[:j] in dictionarySet:
                    words[i] = word[:j]
                    break

        return ' '.join(words)

     解法2的思路也不复杂,它就是先基于dictionary构造Trie树,然后依次在字典树中匹配sentence中的每个单词的最短前缀,最后将所有前缀拼接起来即可。

class Trie:
    def __init__(self):
        self.children = [None] * 26
        self.isEnd = False

    def insert(self, word: str) -> None:
        node = self
        for ch in word:
            ch = ord(ch) - ord("a")
            if not node.children[ch]:
                node.children[ch] = Trie()
            node = node.children[ch]
        node.isEnd = True

class Solution:
    def replaceWords(self, dictionary: List[str], sentence: str) -> str:
        trie = Trie()
        for word_root in dictionary:
            trie.insert(word_root)
        
        words = sentence.split(' ')
        for idx, word in enumerate(words):
            cur = trie
            # Find the shortest prefix and replace the word as it
            for j, ch in enumerate(word):
                if cur.isEnd:
                    words[idx] = word[:j] # a valid prefix
                    break

                # Check whether it has child node or not
                ch = ord(ch) - ord("a") 
                if not cur.children[ch]:
                    break 
                cur = cur.children[ch]
                
        return ' '.join(words)

  关于前缀树的实现可查看文章 Leetcode 208 实现前缀树

posted @ 2022-07-07 15:02  LeonYi  阅读(45)  评论(0编辑  收藏  举报