Tire 字典树模板和算法总结

Trie(前缀树) 的模板应用.

维基百科: https://zh.wikipedia.org/zh-hans/Trie 

使用下面的模板:dfs_search是通过按键搜索有效 单词的题。

 

from collections import defaultdict


class Trie:
    def __init__(self):
        self.children = defaultdict(Trie)
        self.is_word = False
        self.word = ""

    def insert(self, word):
        if not word:
            return

        node = self
        for ch in word:
            node = node.children[ch]

        node.is_word = True
        node.word = word

    def find(self, word):
        node = self
        for c in word:
            if c not in node.children:
                return None
            node = node.children[c]

        return node

    def search(self, word):
        node = self.find(word)
        return node is not None and node.is_word

    def starts_with(self, prefix):
        return self.find(prefix) is not None

    def dfs_search(self, num_str, mapping):
        self.ans = 0
        self.dfs(self, num_str, mapping, layer=0)
        return self.ans

    def dfs(self, node, nums, mapping, layer):
        if layer == len(nums):
            if node.is_word:
                self.ans += 1
                print("found valid word:", node.word)
            return

        if not node.children:
            return

        for ch in mapping[nums[layer]]:
            if ch in node.children:
                self.dfs(node.children[ch], nums, mapping, layer+1)


class Solution:
    def get_valid_words_num(self, num_str: str, word_list):
        mapping = {"2": "abc", "3": "def", "4": "ghi", "5": "jkl",
                        "6": "mno", "7": "pqrs", "8": "tuv", "9": "wxyz"}
        trie = Trie()
        for word in word_list:
            trie.insert(word)

        print(trie.search("tree")) # True
        print(trie.search("used")) # True
        print(trie.search("whatever")) #  False
        print(trie.starts_with("tre")) # True
        print(trie.starts_with("use")) # True

        return trie.dfs_search(num_str, mapping)


print(Solution().get_valid_words_num("8733", ["tree", "used", "tere"]))

  

 

class TrieNode:
    
    def __init__(self):
        self.children = {}
        self.is_word = False
    
    
class Trie:
    
    def __init__(self):
        self.root = TrieNode()

    """
    @param: word: a word
    @return: nothing
    """
    def insert(self, word):
        node = self.root
        for c in word:
            if c not in node.children:
                node.children[c] = TrieNode()
            node = node.children[c]
        
        node.is_word = True

    """
    return the node in the trie if exists 
    """
    def find(self, word):
        node = self.root
        for c in word:
            node = node.children.get(c)
            if node is None:
                return None
        return node
        
    """
    @param: word: A string
    @return: if the word is in the trie.
    """
    def search(self, word):
        node = self.find(word)
        return node is not None and node.is_word

    """
    @param: prefix: A string
    @return: if there is any word in the trie that starts with the given prefix.
    """
    def startsWith(self, prefix):
        return self.find(prefix) is not None
这个实现更加简洁!!!我自己只是已经习惯自己的trie node里加入char word和children了!!!

442. 实现 Trie(前缀树)

中文
English

实现一个 Trie,包含 insert, search, 和 startsWith 这三个方法。

样例

样例 1:

输入: 
  insert("lintcode")
  search("lint")
  startsWith("lint")
输出: 
  false
  true

样例 2:

输入:
  insert("lintcode")
  search("code")
  startsWith("lint")
  startsWith("linterror")
  insert("linterror")
  search("lintcode”)
  startsWith("linterror")
输出: 
  false
  true
  false
  true
  true

注意事项

你可以认为所有的输入都是小写字母a-z。

class Node:
    def __init__(self, char="", word=""):
        self.char = char
        self.word = word
        self.children = {}
    

class Trie:
    
    def __init__(self):
        # do intialization if necessary
        self.root = Node()

    """
    @param: word: a word
    @return: nothing
    """
    def insert(self, word):
        # write your code here
        node = self.root
        for w in word:
            if w not in node.children:
                node.children[w] = Node(char=w)
            node = node.children[w]
        
        node.word = word
        
    """
    @param: word: A string
    @return: if the word is in the trie.
    """
    def search(self, word):
        # write your code here
        node = self.root
        for w in word:
            if w not in node.children:
                return False
            node = node.children[w]
            
        return True if node.word == word else False

    """
    @param: prefix: A string
    @return: if there is any word in the trie that starts with the given prefix.
    """
    def startsWith(self, prefix):
        # write your code here
        node = self.root
        for w in prefix:
            if w not in node.children:
                return False
            node = node.children[w]
        
        return True

 用最前面的模板:

class Node:
    def __init__(self):
        self.is_word = False
        self.children = {}
    

class Trie:
    
    def __init__(self):
        # do intialization if necessary
        self.root = Node()

    """
    @param: word: a word
    @return: nothing
    """
    def insert(self, word):
        # write your code here
        node = self.root
        for w in word:
            if w not in node.children:
                node.children[w] = Node()
            node = node.children[w]
        
        node.is_word = True
        
    """
    @param: word: A string
    @return: if the word is in the trie.
    """
    def search(self, word):
        # write your code here
        assert word
        node = self.find(word)
        return node is not None and node.is_word
        
    def find(self, word):
        node = self.root
        for w in word:
            if w not in node.children:
                return None
            node = node.children[w]
            
        return node

    """
    @param: prefix: A string
    @return: if there is any word in the trie that starts with the given prefix.
    """
    def startsWith(self, prefix):
        # write your code here
        assert prefix
        node = self.find(prefix)
        return node is not None
        

 出错曾  西部ƒ˙qgv

648. 单词替换

难度中等

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

现在,给定一个由许多词根组成的词典和一个句子。你需要将句子中的所有继承词词根替换掉。如果继承词有许多可以形成它的词根,则用最短的词根替换它。

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

示例 1:

输入: dict(词典) = ["cat", "bat", "rat"]
sentence(句子) = "the cattle was rattled by the battery"
输出: "the cat was rat by the bat"

注:

  1. 输入只包含小写字母。
  2. 1 <= 字典单词数 <=1000
  3. 1 <=  句中词语数 <= 1000
  4. 1 <= 词根长度 <= 100
  5. 1 <= 句中词语长度 <= 1000

 

用最笨的方法居然也给过了!!!

class Solution(object):
    def replaceWords(self, dict, sentence):
        """
        :type dict: List[str]
        :type sentence: str
        :rtype: str
        """
        trie = Trie()        
        for w in dict:
            trie.add_word(w)
        words = sentence.split()
        return " ".join([trie.find_neareast(word) for word in words])

        """        
        dict2 = {w for w in dict}
        words = sentence.split()
        return " ".join([self.replace(word, dict2) for word in words])
        """

    def replace(self, word, dict2):
        for i in range(1, len(word)+1):
            if word[:i] in dict2:
                return word[:i]
        return word


class Node(object):
    def __init__(self, char="", word=""):
        self.char = char
        self.word = word
        self.children = {}


class Trie(object):
    def __init__(self):
        self.root = Node()
    
    def add_word(self, word):
        cur = self.root
        for w in word:
            if w not in cur.children:
                cur.children[w] = Node(w)
            cur = cur.children[w]
        cur.word= word        
    
    def find_neareast(self, word):
        cur = self.root
        for w in word:        
            if cur.word:
                return cur.word                
            if w not in cur.children:
                return word            
            cur = cur.children[w]
        return word

473. 单词的添加与查找

中文
English

设计一个包含下面两个操作的数据结构:addWord(word), search(word)

addWord(word)会在数据结构中添加一个单词。而search(word)则支持普通的单词查询或是只包含.a-z的简易正则表达式的查询。

一个 . 可以代表一个任何的字母。

样例

样例 1:

输入:
  addWord("a")
  search(".")
输出: 
  true

样例 2:

输入: 
  addWord("bad")
  addWord("dad")
  addWord("mad")
  search("pad")  
  search("bad")  
  search(".ad")  
  search("b..") 
输出:
  false
  true
  true
  true 

注意事项

你可以认为所有的单词都只包含小写字母 a-z。

class Node:
    def __init__(self):
        self.is_word = False
        self.children = {}


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

    
    def insert(self, word):
        node = self.root
        for ch in word:
            if ch not in node.children:
                node.children[ch] = Node()
            node = node.children[ch]

        node.is_word = True

    
    def search(self, word):
        return self.dfs(self.root, word, i=0)

    def dfs(self, node, word, i):
        if node is None:
            return False
            
        if i == len(word):
            return node.is_word

        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] not in node.children:
                return False
            return self.dfs(node.children[word[i]], word, i + 1)


class WordDictionary:
    def __init__(self):
        self.trie = Trie()

    def addWord(self, word):
        # write your code here
        self.trie.insert(word)

    """
    @param: word: A word could contain the dot character '.' to represent any one letter.
    @return: if the word is in the data structure.
    """
    def search(self, word):
        # write your code here
        return self.trie.search(word)

 无非就是在Trie基础上加了DFS!

  

补充,屏幕按键弹出单词的题目,在公司工作级编程里遇到的一个算法题目:

class Node:
    def __init__(self, val=None):
        self.val = val
        self.is_word = False
        self.children = dict()


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

    def insert(self, word):
        if not word:
            return

        node = self.root
        leaf = None
        for ch in word:
            if ch in node.children:
                node = node.children[ch]
            else:
                node.children[ch] = Node(ch)
                node = node.children[ch]
            leaf = node

        leaf.is_word = True

    def search(self, num_str, mapping):
        self.ans = 0
        self.dfs(self.root, num_str, mapping, layer=0)
        return self.ans

    def dfs(self, node, nums, mapping, layer):
        if layer == len(nums):
            if node.is_word:
                self.ans += 1
            return

        if not node.children:
            return

        for ch in mapping[nums[layer]]:
            if ch in node.children:
                self.dfs(node.children[ch], nums, mapping, layer+1)


class Solution:
    def get_valid_words_num(self, num_str: str, word_list):
        mapping = {"2": "abc", "3": "def", "4": "ghi", "5": "jkl",
                        "6": "mno", "7": "pqrs", "8": "tuv", "9": "wxyz"}
        trie = Trie()
        for word in word_list:
            trie.insert(word)

        return trie.search(num_str, mapping)


print(Solution().get_valid_words_num("8733", ["tree", "used", "tere"]))
print(Solution().get_valid_words_num("2", ["a", "b", "c", "d"]))

  

 

 

 

posted @ 2020-03-27 19:27  bonelee  阅读(463)  评论(1编辑  收藏  举报