沒時間整理了,老呂又講課了@ @ios
Trie即字典樹,又稱單詞查找樹或鍵樹,是一種樹形結構,是一種哈希樹的變種,典型應用是統計和排序大量的字符串(不限於字符串)spa
Trie字典樹主要用於存儲字符串,Trie 的每一個 Node 保存一個字符。用鏈表來描述的話,就是一個字符串就是一個鏈表。每一個 Node 都保存了它的全部子節點。code
插入 查找 前綴查詢 刪除blog
實質:空間換時間排序
eg:字符串
插入單詞:a,ab,abc,abd,acbget
瞅個板子string
給定 \(n\) 個長度不超過 \(10\) 的數字串,問其中是否存在兩個數字串 \(S,T\),使得 \(S\) 是 \(T\) 的前綴hash
hash:時間複雜度起飛io
這不顯然是字典樹的板子麼
#include <iostream> #include <cstdio> #include <queue> #include <cstring> #include <string> #include <cmath> #include <map> using namespace std; const int A = 1e3 + 2; const int B = 1e4 + 2; const int C = 1e5 + 5; const int D = 2e6 + 5; const int inf = 0x3f3f3f3f; const int mod = 99984198447; int read(){ int x = 0,f = 1;char c = getchar(); while(c < '0'||c > '9'){if(c == '-')f = -1;c = getchar();} while(c >= '0'&&c <= '9'){x = x*10 + c - '0';c = getchar();} return x*f; } int T, n, tree[C][11],cnt; bool vis[C],ans; char s[50]; bool insert(char * s){ int len = strlen(s),u = 1; bool flag = false; for(int i = 0;i < len; i++){ int num = s[i] - '0'; if(!tree[u][num]) tree[u][num] = ++cnt;//若是沒有這個字母,就新建一個點 else if(i == len - 1) flag = true;//若是單詞在字典樹中能找到(即字典樹中剛好有這個單詞) u = tree[u][num];//重新建的點後者原來的點向下走,繼續尋找 if(vis[u])flag = true;//字典中的單詞爲新填的單詞的前綴 } vis[u] = true;//將單詞的最後一個字母在字典樹中打上標記 return flag; } void clear(){//注意清零 cnt = 1; memset(vis, 0,sizeof(vis)); memset(tree, 0,sizeof(tree)); ans = false; } int main(){ T = read(); while(T--){ n = read(); clear(); for(int i = 1;i <= n; i++){ scanf("%s", s); if(insert(s))ans = true; } if(!ans)printf("YES\n"); else printf("NO\n"); } }