AcWing 算法基础课 Trie树(字典树、前缀树)总结

Trie树

Trie树又称字典树,前缀树。是一种可以高效查询前缀字符串的树,典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。`做题看到大量字符串或者大量字符就往Trie树或者哈希这边想,因为速度很快

Trie树功能:
1、插入:向字符串集合插入字符串
2、查询:查询某个字符串是否在该字符串集合中(可以在字符串末尾的字符上打上一个标记)
3、统计次数:统计某个字符串在该字符串集合中出现的次数
4、求最长前缀:求两个字符串的最长公共前缀

以模板题:AcWing 835.Trie字符串统计来讲解插入和查询操作
解释: a r r arr arr 数组是一个二维数组,比如这道题,它的列数应该是每个节点的最大分支数,也就是这里有 26 26 26 个字母,每个字母的下一个字母有 26 26 26 种情况,所以要开 26 26 26 列,在最大异或对这道题里面就只有 0 0 0 1 1 1 ,所以开两列就是了。行数的话就看题目的最大长度了

插入操作

void insert()
{
    int p=0;//每次插入都是从第一行开始的,也就是p=0
    for(auto ch:str)
    {
        int u=ch-'a';
        if(!arr[p][u])//如果这个格子还没被用,那么就把这个字母放到这个格子
            arr[p][u]=++idx;
        p=arr[p][u];//指向下一个
    }
    ++cnt[p];//该字符串数目+1
}

假如依次插入
a b , a b c , a d b , ab,abc,adb, ab,abc,adb,
b d , d e f bd,def bd,def
每一次插入的时候, p p p都是从 0 0 0开始。如果首字母没出现过,一定在 a r r arr arr数组的第一行,第二字母及以后的字母才开始按照 i d x idx idx来找位置放,形成链表的结构,插入后的 a r r arr arr数组如下图,格子中的数字,即$idx$表示下一个字母应该放在第几行
在这里插入图片描述

查询字符串出现多少次

int query()
{
    int p=0;
    for(auto ch:str)
    {
        int u=ch-'a';
        if(!arr[p][u])//如果不存在,说明这个字符串不存在,直接返回0
            return 0;
        p=arr[p][u];
    }
    return cnt[p];//返回这个字符串出现的次数
}

用cnt数组保存每个字符串出现的次数,在cnt中用的是最后一个字母的idx来代表这个字符串,虽然idx是代表下一个字母出现的位置,但不影响
比如上面的 a c d acd acd b d bd bd a c d acd acd ′ d ′ 'd' d i d x idx idx 4 4 4 ,那么 c n t [ 4 ] cnt[4] cnt[4] 就代表了 a b d abd abd 这个字符出现的次数, b d bd bd ′ d ′ 'd' d i d x idx idx 6 6 6,那么 c n t [ 6 ] cnt[6] cnt[6] 就代表了 b d bd bd 这个字符串出现的次数,因为对于每个字符串的结尾的 i d x idx idx 是不同的,那么每个 i d x idx idx 就对应了相应的字符串,不会出现重复的情况

T r i e Trie Trie树经典应用:AcWing 143.最大异或对

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值