211. 添加与搜索单词 - 数据结构设计

211. 添加与搜索单词 - 数据结构设计

原始题目链接:https://leetcode.cn/problems/design-add-and-search-words-data-structure/

请你设计一个数据结构,支持 添加新单词 和 查找字符串是否与任何先前添加的字符串匹配 。

实现词典类 WordDictionary :

WordDictionary() 初始化词典对象
void addWord(word) 将 word 添加到数据结构中,之后可以对它进行匹配
bool search(word) 如果数据结构中存在字符串与 word 匹配,则返回 true ;否则,返回 false 。word 中可能包含一些 ‘.’ ,每个 . 都可以表示任何一个字母。

示例:

输入:
[“WordDictionary”,“addWord”,“addWord”,“addWord”,“search”,“search”,“search”,“search”]
[[],[“bad”],[“dad”],[“mad”],[“pad”],[“bad”],[“.ad”],[“b…”]]
输出:
[null,null,null,null,false,true,true,true]

解释:
WordDictionary wordDictionary = new WordDictionary();
wordDictionary.addWord(“bad”);
wordDictionary.addWord(“dad”);
wordDictionary.addWord(“mad”);
wordDictionary.search(“pad”); // 返回 False
wordDictionary.search(“bad”); // 返回 True
wordDictionary.search(“.ad”); // 返回 True
wordDictionary.search(“b…”); // 返回 True

提示:

1 <= word.length <= 25
addWord 中的 word 由小写英文字母组成
search 中的 word 由 ‘.’ 或小写英文字母组成
最多调用 104 次 addWord 和 search

解题思路:

使用字典和一个字符串结束标识构建树中的节点,搜索的过程使用dfs深度优先搜索,具体看注释及代码。

代码实现:

class Node:
    def __init__(self):
        self.children = collections.defaultdict(Node)
        self.is_word = False

class WordDictionary:
    def __init__(self):
        self.root = Node()

    def addWord(self, word: str) -> None:
        cur = self.root
        for char in word:
            cur = cur.children[char]
        
        cur.is_word = True


    def search(self, word: str) -> bool:
        cur = self.root

        def dfs(node, start):
            nonlocal word
            # 递归结束,当前在树中找到的字符串的长度和word的长度一样
            # 并且判断结尾的标识是否为True,如果为False,虽然有全部的字符组成的单词
            # 但树中并没有插入过单词,所以以结尾标识为准
            if start == len(word):
                return True and node.is_word    
            # 开始在树中查找word
            for idx in range(start, len(word)):
                # 如果当前字符不是通配符'.'
                # 正常一层一层递归查找
                if word[idx] != '.':
                    if word[idx] not in node.children:
                        return False
                    else:
                        return dfs(node.children[word[idx]], idx + 1)
                # 如果是'.'
                else:
                    # 当前树没有子树,即没有可查找的范围了,提前结束查找
                    if not node.children:
                        return False
                    else:
                        flag = False

                        # 当前字符是通配符'.',可以匹配树中当前层的所有字符
                        # 所以需要遍历当前所有字符,去查找要找的单词word
                        # 所以要遍历当前层节点的所有子树
                        for key in node.children:
                            res = dfs(node.children[key], idx + 1)
                            flag = flag or res
                            # 如果已经发现匹配项了,直接中断后续迭代
                            if flag:
                                return flag
                        # 所有子树都不满足
                        return False
        return dfs(cur, 0)

参考文献:
https://leetcode.cn/problems/design-add-and-search-words-data-structure/solution/python-qian-zhui-zi-dian-shu-dfsjian-zhi-g6r0/

你可能感兴趣的:(#,字符串,#,树,leetcode)