208. 实现 Trie (前缀树)

实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作。

示例:

Trie trie = new Trie();

trie.insert("apple");
trie.search("apple");   // 返回 true
trie.search("app");     // 返回 false
trie.startsWith("app"); // 返回 true
trie.insert("app");   
trie.search("app");     // 返回 true

说明:

  • 你可以假设所有的输入都是由小写字母 a-z 构成的。
  • 保证所有输入均为非空字符串。

解答:

class Trie:
    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.val = [None] * 26
        self.isleaf = False

    def insert(self, word: str) -> None:
        """
        Inserts a word into the trie.
        """
        root = self
        for i in range(len(word)):
            index = (ord(word[i]) - ord('a')) % 26
            if not root.val[index]:
                root.val[index] = Trie()
            root = root.val[index]
        root.isleaf = True

    def search(self, word: str) -> bool:
        """
        Returns if the word is in the trie.
        """
        root = self
        for i in range(len(word)):
            index = (ord(word[i]) - ord('a')) % 26
            if not root.val[index]:
                return False
            root = root.val[index]        
        return root.isleaf

    def startsWith(self, prefix: str) -> bool:
        """
        Returns if there is any word in the trie that starts with the given prefix.
        """
        root = self
        for i in range(len(prefix)):
            index = (ord(prefix[i]) - ord('a')) % 26
            if not root.val[index]:
                return False
            root = root.val[index]        
        return True

思路:

前缀树是做字符串匹配和子字符串搜索时很好用的一种数据结构。首先根节点为空,从根节点开始将词典中的单词依次建立前缀树,使得具有相同前缀的词在数据结构中有相同的祖先节点。举例而言,假设词典为dict=["apple", "alpha", "banana", "although"],则前缀树为:

                        null
                    a           b
                p       l           a
            p       t       p           n
        l       h               h           a
    e       o                       a           n
        u                                           a
    g
h

判断一个前缀是否在词典中,只需要沿着前缀树查找,匹配整个前缀即可。判断一个词是否在词典中,也是沿着前缀树查找,如果存在一条路径且最终遍历到终止节点,则存在该词。判断终止结点不可以通过去检查当前节点是否存在子节点的方式。举例而言,对于student和students,遍历到‘t’字符时还存在子节点,但这个节点也可以被看做是student的终止节点。因此需要在建树的时候为各个节点做终止标记。

你可能感兴趣的:(208. 实现 Trie (前缀树))