leetcode:208. 实现 Trie (前缀树)

208. 实现 Trie (前缀树)

前缀树的思想:

  • 边表示字符(其实边和点都行)
  • 点的含义表示是否为单词结尾,也可另外再赋予其他含义

图来自于:https://leetcode-cn.com/problems/implement-trie-prefix-tree/solution/208-shi-xian-trie-qian-zhui-shu-bao-gua-insert-sea/

  • insert过程
    • 先进行遍历,把前面所有的公共前缀遍历完
    • 然后在后面把剩下的字符加上
    • 最后end=true,表示这里是一个单词的结尾
  • query过程
    • 先进行遍历,把前面所有的公共前缀遍历完
    • 遍历完公共前缀,这时候end=true,说明前面有这个字符串insert
    • 否则,没有
struct node{
    node(){
        end = false;
    }
    vector<pair<node*, char>> edge;
    bool end;
};

class Trie {
public:

    node* root;
    /** Initialize your data structure here. */
    Trie() {
        root = new node;
    }
    
    /** Inserts a word into the trie. */
    void insert(string word) {
        int k = 0;
        node* nod = root;
        for(int i = 0; i < nod->edge.size()&&k < word.size(); i ++){
            if(nod->edge[i].second == word[k]){
                nod = nod->edge[i].first;
                i = -1;
                k ++;
            }
        }
        while(k < word.size()){
            node* a = new node;
            nod->edge.push_back(make_pair(a, word[k++]));
            nod = a;
        }
        nod->end = true;
    }
    
    /** Returns if the word is in the trie. */
    bool search(string word) {
        int k = 0;
        node* nod = root;
        for(int i = 0; i < nod->edge.size()&&k < word.size(); i ++){
            if(nod->edge[i].second == word[k]){
                nod = nod->edge[i].first;
                i = -1;
                k ++;
            }
        }
        if(k == word.size()&&nod->end) return true;
        return false;
    }
    
    /** Returns if there is any word in the trie that starts with the given prefix. */
    bool startsWith(string prefix) {
                int k = 0;
        node* nod = root;
        for(int i = 0; i < nod->edge.size()&&k < prefix.size(); i ++){
            if(nod->edge[i].second == prefix[k]){
                nod = nod->edge[i].first;
                i = -1;
                k ++;
            }
        }
        if(k == prefix.size()) return true;
        return false;
    }
};

/**
 * Your Trie object will be instantiated and called as such:
 * Trie* obj = new Trie();
 * obj->insert(word);
 * bool param_2 = obj->search(word);
 * bool param_3 = obj->startsWith(prefix);
 */

其他解法

细节上,还可以有很多不同的地方,比如可以直接把node的定义直接放在Trie中,那么每一个节点拿出来都可以看作一个Trie
也可以用数组来表示每个节点的后继,数组只用26个空间。这样在查找是否有相应后继的时候速度加快,不用遍历,但是牺牲了空间。这种写法可以参考面试题 17.17. 多次搜索

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值