簡體   English   中英

Leetcode Python 208. 實現 Trie(前綴樹)

[英]Leetcode Python 208. Implement Trie (Prefix Tree)

有人可以說我的代碼有什么問題嗎,當我下載特定測試用例時,它通過了除最后一個測試用例之外的所有測試用例,預期輸出和實際輸出似乎相同,問題是https://leetcode.com/problems/實現-trie-prefix-tree/description/

編輯1:這是代碼:

class Trie:

def __init__(self):
    """
    Initialize your data structure here.
    """
    self.data = None
    self.children = {}
    self.isWord = False

def insert(self, word):
    """
    Inserts a word into the trie.
    :type word: str
    :rtype: void
    """
    if len(word) == 0:
        return
    if word[0] not in self.children:
        self.children[word[0]] = Trie()
        self.insertHelper(word[1:], self.children[word[0]])
    else:
        self.insertHelper(word[1:], self.children[word[0]])

    if len(word) == 1:
        self.isWord = True

def insertHelper(self, word, trie):
    if len(word) == 0:
        return

    if word[0] not in trie.children:
        trie.children[word[0]] = Trie()
        trie.insertHelper(word[1:], trie.children[word[0]])
    else:
        trie.insertHelper(word[1:], trie.children[word[0]])

    if len(word) == 1:
        trie.isWord = True





def search(self, word):
    """
    Returns if the word is in the trie.
    :type word: str
    :rtype: bool
    """
    if len(word) == 1 and word[0] in self.children and self.isWord:
        return True
    elif len(word) == 0:
        return False

    if word[0] in self.children:
        return self.searchHelper(word[1:], self.children[word[0]])
    else:
        return False

def searchHelper(self, word, trie):
    if len(word) == 1 and word[0] in trie.children and trie.isWord:
        return True
    elif len(word) == 0:
        return False

    if word[0] in trie.children:
        return self.searchHelper(word[1:], trie.children[word[0]])
    else:
        return False



def startsWith(self, prefix):
    """
    Returns if there is any word in the trie that starts with the given prefix.
    :type prefix: str
    :rtype: bool
    """
    if len(prefix) == 0:
        return False
    if prefix[0] in self.children:
        return self.startsWithHelper(prefix[1:], self.children[prefix[0]])
    else:
        return False

def startsWithHelper(self, prefix, trie):
    if len(prefix) == 0:
        return True

    if prefix[0] in trie.children:
        return trie.startsWithHelper(prefix[1:], trie.children[prefix[0]])
    else:
        return False

提前致謝。

我注意到的一個怪癖是將一個空前綴傳遞給startsWith() 如果此方法以 Python str方法startswith()為模型,那么我們期望True

>>> "apple".startswith("")
True
>>>

但是在這種情況下,您的 Trie 會返回False

>>> t = Trie()
>>> t.insert("apple")
>>> t.startsWith("")
False
>>>

下面是我對您的代碼的修改,主要是為了理解它,但我也發現您有冗余,尤其是您的Helper函數。 這段代碼修復了上面提到的怪癖,並且是 Python 3 特定的:

class Trie:

    def __init__(self):
        self.children = {}
        self.isWord = False

    def insert(self, word):
        """
        Inserts a word into the trie.
        :type word: str (or list internally upon recursion)
        :rtype: None
        """

        if not word:
            return

        head, *tail = word

        if head not in self.children:
            self.children[head] = Trie()

        trie = self.children[head]

        if tail:
            trie.insert(tail)
        else:
            self.isWord = True

    def search(self, word):
        """
        Returns True if the word is in the trie.
        :type word: str (or list internally upon recursion)
        :rtype: bool
        """

        if not word:
            return False

        head, *tail = word

        if head in self.children:
            if not tail and self.isWord:
                return True

            return self.children[head].search(word[1:])

        return False

    def startsWith(self, prefix):
        """
        Returns if there is any word in the trie that starts with the given prefix.
        :type prefix: str (or list internally upon recursion)
        :rtype: bool
        """

        if not prefix:
            return True

        head, *tail = prefix

        if head in self.children:
            return self.children[head].startsWith(tail)

        return False

這是另一個使用集合模塊中的'defaultdictionary'來利用'insert'函數中的遞歸的解決方案。

信用: https ://leetcode.com/problems/implement-trie-prefix-tree/discuss/631957/python-elegant-solution-no-nested-dictionaries

class Trie:

def __init__(self):
    """
    Initialize your data structure here.
    """
    self.nodes = collections.defaultdict(Trie)
    self.is_word = False

def insert(self, word: str) -> None:
    """
    Inserts a word into the trie.
    """
    if not word:
        self.is_word = True
    else:
        self.nodes[word[0]].insert(word[1:])
    

def search(self, word: str) -> bool:
    """
    Returns if the word is in the trie.
    """
    if not word:
        return self.is_word
    if word[0] in self.nodes:
        return self.nodes[word[0]].search(word[1:])
                
    return False
    
def startsWith(self, prefix: str) -> bool:
    """
    Returns if there is any word in the trie that starts with the given prefix.
    """
    if not prefix:
        return True
    
    if prefix[0] in self.nodes:
        return self.nodes[prefix[0]].startsWith(prefix[1:])
    
    return False

您的 Trie 對象將被實例化並按如下方式調用:

obj = Trie()
obj.insert(word)
param_2 = obj.search(word)
param_3 = obj.startsWith(prefix)
class TrieNode:
    def __init__(self):
        # each key is a TrieNode
        self.keys = {}
        self.end = False

class Trie:
    def __init__(self):
        self.root = TrieNode()
    # node=this.root gives error "this" is not defined
    def insert(self, word: str, node=None) -> None:
        if node == None:
            node = self.root
        # insertion is a recursive operation
        if len(word) == 0:
            node.end = True
            return
        elif word[0] not in node.keys:
            node.keys[word[0]] = TrieNode()
            self.insert(word[1:], node.keys[word[0]])
        # that means key exists
        else:
            self.insert(word[1:], node.keys[word[0]])
    def search(self, word: str, node=None) -> bool:
        if node == None:
            node = self.root
        # node.end=True means we have inserted the word before
        if len(word) == 0 and node.end == True:
            return True
        # if we inserted apple and then search for app we get false becase we never inserted app so a-p-p last_p.end is not True
        # But startsWith(app) would return True
        elif len(word) == 0:
            return False
        elif word[0] not in node.keys:
            return False
        else:
            # we have to return becasue api expects us to return bool
            return self.search(word[1:], node.keys[word[0]])

    def startsWith(self, prefix: str, node=None) -> bool:
        if node == None:
            node = self.root
        if len(prefix) == 0:
            return True
        elif prefix[0] not in node.keys:
            return False
        else:
            return self.startsWith(prefix[1:], node.keys[prefix[0]])

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM