Add and Search Word

Design a data structure that supports the following two operations:

void addWord(word)
bool search(word)

search(word) can search a literal word or a regular expression string containing only letters a-z or .. A . means it can represent any one letter.

For example:

addWord("bad")
addWord("dad")
addWord("mad")
search("pad") -> false
search("bad") -> true
search(".ad") -> true
search("b..") -> true

比较有意思的题目,主要涉及到通配符'.'的处理,总体思路还是用trie.但是和普通trie上的完全match不同,这里需要在'.'时候做遍历,涉及到backtracking的处理.

代码如下:

class TrieNode(object):
    def __init__(self):
        self.children = {}
        self.hasword = False

class WordDictionary(object):
    def __init__(self):
        """
        initialize your data structure here.
        """
        self.root = TrieNode()
        
    def addWord(self, word):
        """
        Adds a word into the data structure.
        :type word: str
        :rtype: void
        """
        node = self.root
        for i in word:
            if not node.children.get(i):
                node.children[i] = TrieNode()
            node = node.children[i]
        node.hasword = True
        
    def search(self, word):
        """
        Returns if the word is in the data structure. A word could
        contain the dot character '.' to represent any one letter.
        :type word: str
        :rtype: bool
        """
        node = self.root
        return self.dfs(word, 0, node)
            
    def dfs(self, word, i, node):
        if i == len(word) - 1:
            if word[i] != '.':
                if node.children.get(word[i]):
                    return node.children[word[i]].hasword
                else:
                    return False
            else:
                for j in node.children.values():
                    if j.hasword:
                        return True
                return False
        if word[i] == '.':
            for j in node.children.values():
                if self.dfs(word, i+1, node): # backtracking 没有的话,会退回
                    return True
            return False
        else:
            if node.children.get(word[i]):
                return self.dfs(word, i+1, node.children[word[i]])
            else:
                return False
            

 优化版本:

class TrieNode(object):
    def __init__(self):
        self.children = {}
        self.hasword = False

class WordDictionary(object):

    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.root = TrieNode()

    def addWord(self, word):
        """
        Adds a word into the data structure.
        :type word: str
        :rtype: void
        """
        node = self.root
        for c in word:
            if c not in node.children:
                node.children[c] = TrieNode()
            node = node.children[c]
        node.hasword = True    
        
    def search(self, word):
        """
        Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter.
        :type word: str
        :rtype: bool
        """
        node = self.root
        return self.dfs(node, word, 0)
        
    def dfs(self, node, word, i):
        if i == len(word):
            return node.hasword
        if word[i] == '.':
            for c in node.children:
                if self.dfs(node.children[c], word, i+1):
                    return True
            return False    
        else:
            if word[i] in node.children:
                return self.dfs(node.children[word[i]], word, i+1)
            else:
                return False

add的复杂度是单词的长度,search的复杂度最大是遍历树的所有子结点

原文地址:https://www.cnblogs.com/sherylwang/p/5640713.html