数据结构---字典树(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
相关推荐
星火开发设计1 分钟前
二维数组:矩阵存储与多维数组的内存布局
开发语言·c++·人工智能·算法·矩阵·函数·知识
丨康有为丨35 分钟前
算法时间复杂度和空间复杂度
算法
HarmonLTS42 分钟前
Python人工智能深度开发:技术体系、核心实践与工程化落地
开发语言·人工智能·python·算法
a程序小傲1 小时前
京东Java面试被问:RPC调用的熔断降级和自适应限流
java·开发语言·算法·面试·职场和发展·rpc·边缘计算
一分之二~1 小时前
二叉树--层序遍历(迭代和递归)
数据结构·c++·算法·leetcode
zl_vslam1 小时前
SLAM中的非线性优-3D图优化之绝对位姿SE3约束右扰动(十七)
人工智能·算法·计算机视觉·3d
Cestb0n1 小时前
某果app 加密校验算法逆向分析
python·算法·逆向安全
机器学习之心1 小时前
MATLAB基于近红外光谱检测的菠萝含水率预测(多种预处理+PLS)
人工智能·算法·matlab·近红外光谱检测
程序员-King.2 小时前
day166—递归—多边形三角剖分的最低得分(LeetCode-1039)
算法·leetcode·深度优先·动态规划·递归
夏鹏今天学习了吗2 小时前
【LeetCode热题100(94/100)】下一个排列
算法·leetcode·职场和发展