python3 Trie樹及其應用

關於前綴樹基礎知識就不介紹了,通俗總結就是從根節點出發,每個節點都有兩個屬性,一個是這個節點的所有子節點(python3用一個字典記錄這個節點所有後續節點即可)和一個標誌,標誌是否是一個字符串的結束。對於前綴樹而言通常需要有查詢與插入兩種操作。查詢的話就是從根節點出發,依次查找根節點的子節點是否有對應的字符,直到字符結束。插入的話也是從根節點出發,依次查找當前節點的子節點是否有對應的字符,有就不需要重新生成,沒有的話就重新生成一個前綴樹節點,直到最後一個字符插入完畢。具體實現如下所示:

from collections import defaultdict
class TrieNode:
    def __init__(self):
        self.children = defaultdict(TrieNode)
        self.is_word = False
class Trie:

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

    def insert(self, word: str) -> None:
        """
        Inserts a word into the trie.
        """
        cur = self.root
        for w in word:
            cur = cur.children[w]
        cur.is_word = True

    def search(self, word: str) -> bool:
        """
        Returns if the word is in the trie.
        """
        cur = self.root
        for w in word:
            if w not in cur.children:
                return False
            cur = cur.children[w]
        return cur.is_word

    def startsWith(self, prefix: str) -> bool:
        """
        Returns if there is any word in the trie that starts with the given prefix.
        """

        cur = self.root
        for w in prefix:
            if w not in cur.children:
                return False
            cur = cur.children[w]
        return True

關於前綴樹的應用,參見力扣472

前綴樹實現:

from collections import defaultdict
class TrieNode:
    def __init__(self):
        self.children = defaultdict(TrieNode)
        self.is_word = False

class Trie:
    def __init__(self,words):
        self.root = TrieNode()
        for word in words:
            self.insert(word)
    def insert(self,word:str):
        cur = self.root
        for item in word:
            cur = cur.children[item]
        cur.is_word = True

class Solution:
    def findAllConcatenatedWordsInADict(self, words:list):
        Trie_ = Trie(words)
        ans = []
        def dfs(i,word,cur,is_cut):
            if i == len(word):
                return cur.is_word and is_cut
            if cur.is_word:
                if dfs(i,word,Trie_.root,True):
                    return True

            if word[i] not in cur.children:
                return False
            else:
                return dfs(i+1,word,cur.children[word[i]],is_cut)
        for word in words:
            if dfs(0,word,Trie_.root,False):
                ans.append(word)
        return ans

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章