数据结构---字典树(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
相关推荐
长河7 分钟前
Java的GC(垃圾回收)中,标记无用对象的核心方法是可达性分析算法
java·jvm·算法
月光船幽幽25 分钟前
加性偏移外推提升参数识别可靠性
python·算法
Ivanqhz1 小时前
层归一化、残差、前馈网络与激活函数简述
服务器·数据库·人工智能·深度学习·算法
不会就选b2 小时前
算法日常・每日刷题--<动态规划>3
数据结构·算法
-dzk-3 小时前
【堆】LC 347.前 K 个高频元素
算法·堆
H.莓飛3 小时前
【数据结构】栈_OJ题
linux·数据结构·算法·centos
Zootopia6263 小时前
多架 eVTOL集群排班调度方案思考
人工智能·算法·数学建模·matlab·动态规划·无人机·evtol
和裕3 小时前
年度框架直供 vs 零散按需采购:定制纸箱采购成本、交付与服务核心区别全对比
大数据·运维·网络·人工智能·算法
朝朝辞暮i3 小时前
C++ 第 13 课:值传递 —— 为什么函数里改了,外面却没变?
java·c++·算法
淡海水4 小时前
02-02-原理篇-分代GC
算法·unity·c#·游戏引擎·.net·gc