• 力扣 6183周赛:字符串的前缀分数和 ——Trie树


    通过这道周赛题,来记录一下,Trie树(前缀树),又称字典树,字符查找树

    首先Trie树的作用是快速存储和查询字符串集合的一种树

    现在只讲模板,进行自己日后复习了

    先设全局变量

    int tr[N][26];     //26对应26个英文单词,可以看做26叉树

    int cnt[N];        //cnt[]存储以某节点结尾的字符串个数(同时也起标记作用)

    int idx;             //idx表示当前要插入的节点是第几个,每创建一个节点值+1

     构造插入函数

    1. //传统Trie树是记录最后一个字符为结尾的字符串数量,本题是需要记录每个字符!
    2. void insert(string&word) //插入函数,插入的同时维护trie树结构
    3. {
    4. int p=0; //初始p为0,类似指针,指向当前节点
    5. for(auto&c:word) //遍历该单词的字符
    6. {
    7. int u=c-'a'; //算出当前字符的下标,即在tr[i][j]中j的下标
    8. if(!tr[p][u]) tr[p][u]=++idx; //如果当前trie树没有该下标,则构建
    9. p=tr[p][u]; //同时更新p,使p指向这个遍历的字符所在节点
    10. cnt[p]++; //更新cnt数组,cnt数组是以当前节点结束的字符串数量
    11. }
    12. }

    构造query函数

    1. int query(string&word) //构造查询函数
    2. {
    3. int p=0,res=0; //同样初始化p为0,同时定义一个返回值 res
    4. for(auto&c:word) //遍历word
    5. {
    6. int u=c-'a';
    7. p=tr[p][u];
    8. res+=cnt[p]; //把res加上以这个单词的字符为结尾的计数数组cnt
    9. }
    10. return res; //最后res得到的就是这个单词全部的非空前缀总和
    11. }

    题目Trie树解法代码

    1. //使用TRIE树
    2. const int N=1e6+10;
    3. int tr[N][26],cnt[N],idx; //trie树模板
    4. class Solution {
    5. public:
    6. void insert(string&word)
    7. {
    8. int p=0;
    9. for(auto&c:word)
    10. {
    11. int u=c-'a';
    12. if(!tr[p][u]) tr[p][u]=++idx;
    13. p=tr[p][u];
    14. cnt[p]++;
    15. }
    16. }
    17. int query(string&word)
    18. {
    19. int p=0,res=0;
    20. for(auto&c:word)
    21. {
    22. int u=c-'a';
    23. p=tr[p][u];
    24. res+=cnt[p];
    25. }
    26. return res;
    27. }
    28. vector<int> sumPrefixScores(vector& words) {
    29. idx=0;
    30. memset(tr,0,sizeof(tr));
    31. memset(cnt,0,sizeof cnt);
    32. for(auto&c:words) insert(c);
    33. vector<int>res;
    34. for(auto&word:words)
    35. {
    36. res.push_back(query(word));
    37. }
    38. return res;
    39. }
    40. };

    题目字符串哈希解法代码

    1. //可看我之前写得字符串哈希博客,里面有字符串哈希理解
    2. //字符串哈希需要两次遍历,第一次是维护hash表,第二次是将每个单词答案加入答案数组里
    3. typedef unsigned long long ULL;
    4. const int P=13331;
    5. class Solution {
    6. public:
    7. vector<int> sumPrefixScores(vector& words) {
    8. unordered_mapint> hash;
    9. for(auto&word:words)
    10. {
    11. ULL x=0;
    12. for(char c:word)
    13. {
    14. x=x*P+c;
    15. hash[x]++; //记录当前子字符串
    16. }
    17. }
    18. vector<int> ans;
    19. for(auto&s:words)
    20. {
    21. ULL x=0;
    22. int t=0;
    23. for(auto&c:s)
    24. {
    25. x=x*P+c;
    26. t+=hash[x];
    27. }
    28. ans.push_back(t);
    29. }
    30. return ans;
    31. }
    32. };

     

  • 相关阅读:
    Mysql优化笔记
    rk3128-android7-allapp按键和hotseat栏
    20230912在ubuntu18.04下使用pigz来提高tar命令压缩解压缩的速度
    代理IP供应商的代理池大小怎么看?
    四元数、罗德里格斯公式、欧拉角、旋转矩阵推导和资料
    DGS之Mutations
    2023年云计算的发展趋势如何?
    【汇编语言王爽】进阶-笔记 p22--p40
    spring boot单元测试
    Apache 网站服务基础
  • 原文地址:https://blog.csdn.net/weixin_60630451/article/details/126924592