当前位置: 首页 > news >正文

从零备战蓝桥杯——Trie 字典树(前缀树)

双非刷leetcode备战2023年蓝桥杯,qwq加油吧,无论结果如何总会有收获!一起加油,我是跟着英雄哥的那个思维导图刷leetcode的,大家也可以看看所有涉及到的题目用leetcode搜索就可以哦,因为避让添加外链,一起加油!!!
零基础小白也可以看,因为我就是!
请添加图片描述

文章目录

  • Trie 字典树(前缀树)
      • 插入
      • 找串和找串的前缀
      • 相关题目:[leetcode:208. 实现 Trie (前缀树)]
      • 相关题目:[leetcode:14. 最长公共前缀]
      • 相关题目:[LeetCode211. 添加与搜索单词 - 数据结构设计]
      • 相关题目:[820. 单词的压缩编码]

Trie 字典树(前缀树)

啥叫字典树其实就是找一个前缀相同的东西,是一个类似于树的结构,来保存一个串。

字典树的基本结构:

#include <iostream>
#include <string.h>
#include <string>
using namespace std;
class Trie
{
private:
    bool isEnd;     //判断是否为结尾
    Trie *next[26]; //保存着下一个数是26位数哪一个的地址
public:
    Trie()
    {
        isEnd=false;
        memset(next,0,sizeof(next));
    }

    
};

在这里插入图片描述

这个地方的技巧就是用一个26个字母的数组来标记26个字母哪个存在如果存在就下一个如果不存在就建一个新Trie。这个树的储存结构其实是好多个二十六个字母的Trie的地址组成的。就可以达到快速查找啊插入啊的效果。


插入

如果没有就建一个新Trie,然后下一个肯定有了,然后直接访问下一个就行了,等全访问完了就标记isEnd=true表示这个串插入完了;

 void insert(string word) //插入一个字符串
    {
        Trie *node = this;
        for (int i = 0; i < word.length(); i++)
        {
            if (node->next[word[i] - 'a'] == NULL) //如果没有就新建一个trie;
            {
                node->isEnd[word[i] - 'a'] = new Trie();
            }
            node=node->next[word[i]-'a'];//访问下一个;

        }
        node->isEnd=true;//标记这个trie结束了
    }


找串和找串的前缀

找串:

从头开始访问,如果有就下一个,如果没有就返回false。如果全访问完了,就返回isEnd;(没访问完就代表没有)

    bool search(string word)
    {
        Trie * node=this;
        for (int i = 0; i < word.length(); i++)
        {
            node =node->next[word[i]-'a'];
            if(node==NULL)
            {
                return false;
            }
        }
        retrun node->isEnd;
   	}

找串的前缀:

与找串相同不过不需要全访问完了,只要期间都有,把这个前缀访问完了就可以返回true

bool startsWith(string prefix)
    {
        Trie * node=this;
        for (int i = 0; i < word.length(); i++)
        {
            node =node->next[word[i]-'a'];
            if(node==NULL)
            {
                return false;
            }
        }
        retrun true;
    }



相关题目:[leetcode:208. 实现 Trie (前缀树)]

题目代码:

class Trie
{
private:
    bool isEnd;     //判断是否为结尾
    Trie *next[26]; //保存着下一个数是26位数哪一个的地址
public:
    Trie()
    {
        isEnd=false;
        memset(next,0,sizeof(next));
    }

    void insert(string word) //插入一个字符串
    {
        Trie *node = this;
        for (int i = 0; i < word.length(); i++)
        {
            if (node->next[word[i] - 'a'] == NULL) //如果没有就新建一个trie;
            {
                node->next[word[i] - 'a'] = new Trie();
            }
            node=node->next[word[i]-'a'];//访问下一个;

        }
        node->isEnd=true;//标记这个trie结束了
    }

    bool search(string word)
    {
        Trie * node=this;
        for (int i = 0; i < word.length(); i++)
        {
            node =node->next[word[i]-'a'];
            if(node==NULL)
            {
                return false;
            }
        }
        return node->isEnd;
    }

    bool startsWith(string prefix)
    {
        Trie * node=this;
        for (int i = 0; i < prefix.length(); i++)
        {
            node =node->next[prefix[i]-'a'];
            if(node==NULL)
            {
                return false;
            }
        }
        return true;
    }
};

在这里插入图片描述


相关题目:[leetcode:14. 最长公共前缀]

代码(字典树版)

class Trie
{
private:
    bool end;

    Trie *next[26];

public:
    Trie()
    {
        end = false;
        memset(next, 0, sizeof(next));
    }
    void insertEle(string s)
    {
        Trie *node = this;
        for (int i = 0; i < s.length(); i++)
        {
            if (node->next[s[i] - 'a'] == NULL)
            {
                node->next[s[i] - 'a'] = new Trie();
            }
            node = node->next[s[i] - 'a'];
        }
        node->end = true;
    }
    string findSame()
    {
        Trie *node = this;
        string s = "";
        while (1)
        {
            int flag = 0;
            int t = 0;
            for (int i = 0; i < 26; i++)
            {
                if (node->next[i] != NULL)
                {
                    flag++;
                    t = i;
                }
            }
                        if (node->end)
            {
                return s;
            }
            if (flag == 1)
            {
                s = s + (char)('a' + t);
                node = node->next[t];
            }
            else
            {
                return s;
            }


        }
        return s;
    }
};
class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) {
        Trie* t=new Trie();
        while(!strs.empty())
        {
            t->insertEle (strs.back());
            strs.pop_back();
        }
            return t->findSame();
    }
};

在这里插入图片描述

相关题目:[LeetCode211. 添加与搜索单词 - 数据结构设计]

class Trie
{
public:
    bool end;
    Trie *next[26];
    Trie()
    {
        end = false;
        memset(next, 0, sizeof(next));
    }
};
class WordDictionary
{
private:
    Trie *root1;

public:
    WordDictionary()
    {
        root1 = new Trie();
    }
    void addWord(string word)
    {
        Trie *root = root1;
        for (int i = 0; i < word.length(); i++)
        {
            if (root->next[word[i] - 'a'] == NULL)
            {
                root->next[word[i] - 'a'] = new Trie();
            }
            root = root->next[word[i] - 'a'];
        }
        root->end = true;
    }
    bool search(string word)
    {
        return dfs(root1, word, 0);
    }

    bool dfs(Trie *root, string &word, int start)
    {
        if (start == word.length())
        {
            return root->end;
        }
        if (word[start] == '.')
        {
            int flag = 0;
            for (int i = 0; i < 26; i++)
            {
                if (root->next[i])
                {
                    if (dfs(root->next[i], word, start + 1))
                    {
                        return true;
                    }
                }
            }
        }
        else if (root->next[word[start] - 'a'] == NULL)
        {
            return false;
        }

        else
        {
            return dfs(root->next[word[start] - 'a'], word, start + 1);
        }
        return false;
    }
};

在这里插入图片描述

相关题目:[820. 单词的压缩编码]

//这个要注意要把单词少的放在后面

class Trie
{
private:
    bool isEnd;     //判断是否为结尾
    Trie *next[26]; //保存着下一个数是26位数哪一个的地址
public:
    Trie()
    {
        isEnd = false;
        memset(next, 0, sizeof(next));
    }

    void insert(string word) //插入一个字符串
    {
        Trie *node = this;
        for (int i = word.length() - 1; i >= 0; i--)
        {
            if (node->next[word[i] - 'a'] == NULL) //如果没有就新建一个trie;
            {
                node->next[word[i] - 'a'] = new Trie();
            }
            node = node->next[word[i] - 'a']; //访问下一个;
        }
        node->isEnd = true; //标记这个trie结束了
    }

    bool startsWith(string prefix)
    {
        Trie *node = this;
        for (int i = prefix.length() - 1; i >= 0; i--)
        {
            node = node->next[prefix[i] - 'a'];
            if (node == NULL)
            {
                return false;
            }
        }
        return true;
    }
};
class Solution {
public:
    int minimumLengthEncoding(vector<string>& words) {
         for (int i = 0; i < words.size(); i++)
    {
        for (int j = 0; j < words.size() - i - 1; j++)
        {
            if (words[j].length() < words[j + 1].length())
            {
                string t = words[j];
                words[j] = words[j + 1];
                words[j + 1] = t;
            }
        }
    }//冒泡排序
        Trie* root=new Trie();
        int count =0;
        for(int i=0;i<words.size();i++)
        {
            if(root->startsWith(words[i]))//如果能找到
            {
                continue;
            }
            else
            {
                root->insert(words[i]);
                count+=(words[i].length()+1);
            }//如果找不到
        }
        return count;
    }

};

在这里插入图片描述

请添加图片描述

Love is worth years.❤
热爱可抵岁月漫长。

本文部分思路来源于网络如有侵权联系删除~

相关文章:

  • m通信系统中基于相关峰检测的信号定时同步算法的FPGA实现
  • Unity 之 Mac App Store 内购过程解析(购买非消耗道具 | 恢复购买 | 支付验证)
  • AD四层板总结
  • 【MLOPs】Docker
  • js执行机制
  • Pytorch+Python实现人体关键点检测
  • 【1024】程序员福利
  • Redis产生的问题:在关闭虚拟机退出后重启发生网卡启动失败
  • 浅谈Vue3的优势
  • 如何在Vue+ElementUI项目中使用iconfont图标库
  • Python基础加强学习
  • C语言-简单的程序设计
  • 链队列基本操作
  • 多旋翼无人机仿真 rotors_simulator:基于PID控制器的位置控制---高度控制
  • Python是“真火”还是“虚火”?
  • 实现windows 窗体的自己画,网上摘抄的,学习了
  • AWS实战 - 利用IAM对S3做访问控制
  • k8s 面向应用开发者的基础命令
  • Mithril.js 入门介绍
  • Vue学习第二天
  • 不用申请服务号就可以开发微信支付/支付宝/QQ钱包支付!附:直接可用的代码+demo...
  • 成为一名优秀的Developer的书单
  • 构建工具 - 收藏集 - 掘金
  • 前端自动化解决方案
  • 微信小程序填坑清单
  • 一起来学SpringBoot | 第十篇:使用Spring Cache集成Redis
  • HanLP分词命名实体提取详解
  • hi-nginx-1.3.4编译安装
  • Java性能优化之JVM GC(垃圾回收机制)
  • Nginx惊现漏洞 百万网站面临“拖库”风险
  • 通过调用文摘列表API获取文摘
  • # 20155222 2016-2017-2 《Java程序设计》第5周学习总结
  • # Python csv、xlsx、json、二进制(MP3) 文件读写基本使用
  • (cljs/run-at (JSVM. :browser) 搭建刚好可用的开发环境!)
  • (C语言)strcpy与strcpy详解,与模拟实现
  • (第9篇)大数据的的超级应用——数据挖掘-推荐系统
  • (二)构建dubbo分布式平台-平台功能导图
  • (附源码)springboot码头作业管理系统 毕业设计 341654
  • (论文阅读31/100)Stacked hourglass networks for human pose estimation
  • (四)鸿鹄云架构一服务注册中心
  • (转) Android中ViewStub组件使用
  • .form文件_SSM框架文件上传篇
  • .gitignore文件—git忽略文件
  • .NET 应用启用与禁用自动生成绑定重定向 (bindingRedirect),解决不同版本 dll 的依赖问题
  • .NET/C# 异常处理:写一个空的 try 块代码,而把重要代码写到 finally 中(Constrained Execution Regions)
  • .NET开源全面方便的第三方登录组件集合 - MrHuo.OAuth
  • .NET是什么
  • [C++基础]-入门知识
  • [CakePHP] 在Controller中使用Helper
  • [codevs] 1029 遍历问题
  • [cogs2652]秘术「天文密葬法」
  • [daily][archlinux][game] 几个linux下还不错的游戏
  • [Java]深入剖析常见排序
  • [javaSE] GUI(事件监听机制)
  • [Java开发之路](14)反射机制