leetcode208.前缀树

用unordered_map保存一个节点的所有孩子,其中字符为key和对应节点指针为value,节点还需要一个属性值is_end表明是否是一个单词的结尾

class TrieNode
{
public:
    TrieNode(bool end= false) {is_end=end;}
    ~TrieNode()
    {
        for(auto elem:branches)
            delete(elem.second);
    }

    TrieNode* find_node(char ch)  //在该节点的孩子节点中找ch字符的节点
    {
        if(branches.find(ch)==branches.end())
            return nullptr;
        else
            return branches[ch];
    }
    bool is_end; //用于标识节点是否是一个单词的结尾
    unordered_map<char,TrieNode*> branches; //用来保存孩子节点以及对应的字符,因为后续需要判断孩子节点中是否有某个字符的节点,因此用map查询会高效一点。也可以用vector,其中下标为字符,值为节点指针

};

class Trie {
public:
    /** Initialize your data structure here. */
    Trie() {root = new TrieNode();}
    ~Trie() {delete(root);} //在TrieNode里会递归删除所有节点

    /** Inserts a word into the trie. */
    void insert(string word) {
        TrieNode* cur = root;
        int i=0;
        for(;i<word.size();++i) //找第一个不在前缀树里的字母
        {
            TrieNode* tmp = cur->find_node(word[i]);
            if(tmp== nullptr) break;//没找到,跳出循环
            else
            {
                cur = tmp;
                if(i==word.size()-1)  //考虑要插入的已经存在,但只是某个词的前缀,因此需要更改其is_end属性
                    cur->is_end = true;
            }
        }

        for(;i<word.size();++i)  //将单词的剩余部分添加到树里
        {
            cur->branches[word[i]] = new TrieNode(i==word.size()-1? true: false);  //如果是单词结束,则其is_end属性要为true
            cur = cur->branches[word[i]];  //指向刚插入的节点
        }
    }

    /** Returns if the word is in the trie. */
    bool search(string word) {
        TrieNode* cur = root;
        for(int i=0;i<word.size();++i)
        {
            TrieNode* tmp=cur->find_node(word[i]);
            if(tmp!= nullptr)  //如果该字符存在
                cur=tmp;
            else
                return false;
        }
        if(cur->is_end)
            return true;
        else   //如果只是前缀,则返回false
            return false;
    }

    /** Returns if there is any word in the trie that starts with the given prefix. */
    bool startsWith(string prefix) {
        TrieNode* cur = root;
        for(int i=0;i<prefix.size();++i)
        {
            TrieNode* tmp=cur->find_node(prefix[i]);
            if(tmp!= nullptr)  //如果该字符存在
                cur=tmp;
            else
                return false;
        }
        return true;
    }
private:
    TrieNode* root;  //根节点
};

参考:
https://leetcode.com/problems/implement-trie-prefix-tree/discuss/59067/Two-C%2B%2B-O(n)-Solutions%3A-Array-or-Hashtable

猜你喜欢

转载自blog.csdn.net/aikudexue/article/details/89712676
今日推荐