[leetcode] Implement Trie (Prefix Tree)

Problem Description:

Implement a trie with insertsearch, and startsWith methods.

Note:
You may assume that all inputs are consist of lowercase letters a-z.

继续我的每天水题之路。

这是一道小的设计题,设计一个字典树节点的数据结构,从而实现字典树的插入,查找字符串和查找前缀。

由于题目假设所有的输入都是a-z的26个字母,这道题目就可以直接用数组来表示每个节点的26个孩子指针(next)。另外,为了区分完整的字符串和字符串前缀,我们需要在每个节点处标记该处是不是字符串的结尾,本来一个bool就够用了,我这里用的是int表示的cnt,这样还可以实现字符串的计数功能。

有了字典树的结构之后,那三个操作都是很显然的事情,这里不再赘述。

下面简单分析该方法的优缺点:

优点,虽然用数组来存储,但是可以直接用字符来寻址(孩子节点的位置),相当于hash。上述三种操作的时间复杂度都是O(k),k是输入字符串的长度。

缺点,内存消耗特别大,每层节点数目按照26倍进行指数增长,处理的字符串肯定不能太长。这里还有一个小的改进可以稍微减少一点空间的消耗。细看我的实现,可以发现当插入一个字符时,不管它是否还有孩子节点,都直接预先分配了26个空的孩子节点指针。我们可以等某个节点有了子孩子之后,再一次性分配内存。


class TrieNode {
public:
    // Initialize your data structure here.
    TrieNode() {
        cnt = 0;
        next.assign(26, NULL);
    }
    int cnt;
    vector<TrieNode*> next;
};

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

    // Inserts a word into the trie.
    void insert(string word) {
        TrieNode* ptr = root;
        for(int i = 0; i < word.length(); ++i)
        {
            int idx = word[i] - 'a';
            if(ptr->next[idx] == NULL)
            {
                ptr->next[idx] = new TrieNode();
            }
            ptr = ptr->next[idx];
        }
        ++(ptr->cnt);
    }

    // Returns if the word is in the trie.
    bool search(string word) {
        TrieNode* ptr = root;
        for(int i = 0; i < word.length(); ++i)
        {
            int idx = word[i] - 'a';
            if(ptr->next[idx] == NULL)
            {
                return false;
            }
            ptr = ptr->next[idx];
        }
        if(ptr->cnt > 0) return true;
        else return false;
    }

    // Returns if there is any word in the trie
    // that starts with the given prefix.
    bool startsWith(string prefix) {
        TrieNode* ptr = root;
        for(int i = 0; i < prefix.length(); ++i)
        {
            int idx = prefix[i] - 'a';
            if(ptr->next[idx] == NULL)
            {
                return false;
            }
            ptr = ptr->next[idx];
        }
        return true;
    }

private:
    TrieNode* root;
};


你可能感兴趣的:([leetcode] Implement Trie (Prefix Tree))