数据结构---字典树(Tire)

字典树是一种能够快速插入和查询字符串的多叉树结构,节点的编号各不相同,根节点编号为0

Trie树,即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种。

核心思想也是通过空间来换取时间上的效率

在一定情况下字典树的效率要比哈希表要高

字典树在解决公共前缀的使用,所以叫前缀树

先说如何创建字典树

这个是只有26个小写字母存放的字典树

cpp 复制代码
class TrieNode{
public:
    TrieNode* next[26];
    bool isword;
    TrieNode(){
        memset(next,NULL,sizeof(next));
        isword=false;
    }
    ~TrieNode(){
        for(int i=0;i<26;i++)if(next[i])delete next[i];
    }
};

也可以直接用c++中的特殊的数据结构来实现

cpp 复制代码
struct Node {
    unordered_map<int, Node*> son;
    int cnt = 0;
};

但是在下面必须要对根节点进行补充,根节点为空

cpp 复制代码
Node *root = new Node();

leetcode3043. 最长公共前缀的长度-CSDN博客

leetcode3042. 统计前后缀下标对 I-CSDN博客

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

这道题之前用的暴力去模拟这个过程,效率太低,,采用前缀树来解决

cpp 复制代码
class Solution {
public:

    long long countPrefixSuffixPairs(vector<string>& words) {
        long long cnt=0;
        int i,j;
        for(i=0;i<words.size()-1;i++){
            for(j=i+1;j<words.size();j++){
                       if(words[j].find(words[i])==0 && words[j].rfind(words[i])==words[j].length()-words[i].length()){
                           cnt++;
                       }
            }
        }
        return cnt;
    }
};

但是前缀树解决的是前缀的问题,这道题让解决的是前缀和后缀的问题,所以想要把这个字符串转变一下来解决,

【1】首先我先到的是建造两个前缀树,一个正向前缀树,一个反向前缀树

【2】可以用一个pair去储存步骤1的过程

正 ab abcdab

反 ba badcba

(a,b),(b,a)\] \[(a,b),(b,a),.....

由此可见如果是前后缀的话,应该会在pair列表中出现

python 复制代码
class Node:
    __slots__ = 'son', 'cnt'

    def __init__(self):
        self.son = dict()
        self.cnt = 0

class Solution:
    def countPrefixSuffixPairs(self, words: List[str]) -> int:
        ans = 0
        root = Node()
        for t in words:
            z = self.calc_z(t)
            cur = root
            for i, c in enumerate(t):
                if c not in cur.son:
                    cur.son[c] = Node()
                cur = cur.son[c]
                if z[-1 - i] == i + 1:  # t[-1-i:] == t[:i+1]
                    ans += cur.cnt
            cur.cnt += 1
        return ans

    def calc_z(self, s: str) -> List[int]:
        n = len(s)
        z = [0] * n
        l, r = 0, 0
        for i in range(1, n):
            if i <= r:
                z[i] = min(z[i - l], r - i + 1)
            while i + z[i] < n and s[z[i]] == s[i + z[i]]:
                l, r = i, i + z[i]
                z[i] += 1
        z[0] = n
        return z
相关推荐
DuHz几秒前
242-267 GHz双基地超外差雷达系统:面向精密太赫兹传感与成像的65nm CMOS实现——论文阅读
论文阅读·物联网·算法·信息与通信·毫米波雷达
AI科技星34 分钟前
时空的固有脉动:波动方程 ∇²L = (1/c²) ∂²L/∂t² 的第一性原理推导、诠释与验证
数据结构·人工智能·算法·机器学习·重构
2401_841495641 小时前
【LeetCode刷题】寻找重复数
数据结构·python·算法·leetcode·链表·数组·重复数
罗技1231 小时前
Easysearch 集群监控实战(下):线程池、索引、查询、段合并性能指标详解
前端·javascript·算法
一路往蓝-Anbo1 小时前
C语言从句柄到对象 (七) —— 给对象加把锁:RTOS 环境下的并发安全
java·c语言·开发语言·stm32·单片机·嵌入式硬件·算法
中國龍在廣州1 小时前
谈谈2025年人工智能现状及发展趋势分析
人工智能·深度学习·算法·自然语言处理·chatgpt·机器人·机器人学习
C雨后彩虹2 小时前
二维伞的雨滴效应
java·数据结构·算法·华为·面试
youngee112 小时前
hot100-60子集
数据结构·算法
郝学胜-神的一滴2 小时前
Linux线程属性设置分离技术详解
linux·服务器·数据结构·c++·程序人生·算法
Timmylyx05182 小时前
2025年最后一搏—— Educational Codeforces Round 186 (Rated for Div. 2) 题解
算法·codeforces·比赛日记