Top 100 Linked Question 修炼------第208题

本文深入解析Trie数据结构的原理及其实现,包括插入、查找和前缀匹配等功能,并对比不同实现方式,如使用列表、字典和自定义节点结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

208. Implement Trie (Prefix Tree)

题目链接

题目解释:完成一个triez这样的数据结构,要求其具备有插入(insert)、查找(search)、开始元素(startsWiths)方法。

Example:

Trie trie = new Trie();

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

注意:

  • 所有输入的元素都是小写字母(从a-z)
  • 所有的输入都是非空字符串

题目分析:完成一个数据结构,能够实现我们常见的功能。首先映入我们脑海的,也就是最简单的内容,直接按照栈来进行操作,这也是映入我脑海的第一想法,于是乎,code就来了:

class Trie(object):
    def __init__(self):
        """
        Initialize your data structure here.,维护一个list
        """
        self.res=[]

    def insert(self, word):
        """
        Inserts a word into the trie.
        :type word: str
        :rtype: None
        """
        self.res.append(word)

    def search(self, word):
        """
        Returns if the word is in the trie.
        :type word: str
        :rtype: bool
        """
        for target in self.res:
            if target==word:
                return True
        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
        """
        for target in self.res:
            if len(target)<len(prefix):
                continue
            if target[:len(prefix)]==prefix:
                return True
        return False

是不是觉得很开心,一下子就能解决Leetcode上面的medium类型的题?too young too simple.简单是不可能这么简单的,一辈子都不可能这么简单的,那么接下来就是可以学习重点内容了:字典树

what is prefix tree?

简而言之,就是采用字典构成的树,例如,一个保存了8个键的trie结构,"A", "to", "tea", "ted", "ten", "i", "in", and "inn".如下图所示:

字典树主要有如下三点性质:

1. 根节点不包含字符,除根节点意外每个节点只包含一个字符。

2. 从根节点到某一个节点,路径上经过的字符连接起来,为该节点对应的字符串。

3. 每个节点的所有子节点包含的字符串不相同。

有了上面的这个铺垫,我们可以学习一下字典树的实现方式:

【下面的代码是学习Grandyang大佬的】,具体的可以打开链接参考。

class TrieNode {
public:
    // Initialize your data structure here.
    TrieNode *child[26];
    bool isWord;
    TrieNode() : isWord(false){
        for (auto &a : child) a = NULL;
    }
};

class Trie {
public:
    Trie() {
        root = new TrieNode();
    }

    // Inserts a word into the trie.
    void insert(string s) {
        TrieNode *p = root;
        for (auto &a : s) {
            int i = a - 'a';
            if (!p->child[i]) p->child[i] = new TrieNode();
            p = p->child[i];
        }
        p->isWord = true;
    }

    // Returns if the word is in the trie.
    bool search(string key) {
        TrieNode *p = root;
        for (auto &a : key) {
            int i = a - 'a';
            if (!p->child[i]) return false;
            p = p->child[i];
        }
        return p->isWord;
    }

    // Returns if there is any word in the trie
    // that starts with the given prefix.
    bool startsWith(string prefix) {
        TrieNode *p = root;
        for (auto &a : prefix) {
            int i = a - 'a';
            if (!p->child[i]) return false;
            p = p->child[i];
        }
        return true;
    }

private:
    TrieNode* root;
};

我们也可以采用另外一种字典树的实现方式:结点都是采用字母组成,不会将前面的内容集合起来,即每个Node里面都是单个字符,如‘t’,'e','a'等。同时,我们还对每个Node设计的数据结构还是包含了一个isword的标志位,从而判断是否是我们想要的单词,总体来说,这种实现方式稍微复杂一点,但是理解起来是简单一些的。

class Node(object):
    def __init__(self):
        self.children = collections.defaultdict(Node)
        # 标记符,判断这个内容是否是word
        self.isword = False

class Trie(object):
    def __init__(self):
        """
        Initialize your data structure here.初始化根节点,根节点里面不包含元素
        """
        self.root = Node()

    def insert(self, word):
        """
        Inserts a word into the trie.
        :type word: str
        :rtype: void
        """
        current = self.root
        for w in word:
            current = current.children[w]
        current.isword = True

    def search(self, word):
        """
        Returns if the word is in the trie.
        :type word: str
        :rtype: bool
        """
        current = self.root
        for w in word:
            current = current.children.get(w)
            if current == None:
                return False
        return current.isword

    def startsWith(self, prefix):
        """
        Returns if there is any word in the trie that starts with the given prefix.
        :type prefix: str
        :rtype: bool
        """
        current = self.root
        for w in prefix:
            current = current.children.get(w)
            if current == None:
                return False
        return True
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值