并查集
int fa[100010];
void init(int n) {
for (int i = 1; i <= n; i++)
fa[i] = i;
}
int get(int x) {
if (fa[x] == x)
return x;
return fa[x] = get(fa[x]); //路径压缩,防止链式结构
}
void merge(int x, int y) {
fa[get(x)] = get(y);
}
优化:
class UnionFind {
int n;
vector<int> parent, size;
public:
UnionFind(int n) {
this->n = n;
parent = vector<int>(n);
size = vector<int>(n, 1);
for (int i = 0; i < n; ++i)
parent[i] = i;
}
int find(int idx) {
if (parent[idx] == idx)
return idx;
return parent[idx] = find(parent[idx]);
}
void connect(int a, int b) {
int fa = find(a), fb = find(b);
if (fa != fb) {
if (size[fa] > size[fb]) {
parent[fb] = fa;
size[fa] += size[fb];
} else {
parent[fa] = fb;
size[fb] += size[fa];
}
}
}
Trie树
模板一
struct Node {
bool isEnd = false;
shared_ptr<Node> son[26];
};
class Trie {
shared_ptr<Node> root;
public:
/** Initialize your data structure here. */
Trie() { root = make_shared<Node>(); }
/** Inserts a word into the trie. */
void insert(string word) {
auto node = root;
for (char c : word) {
int x = c - 'a';
if (!node->son[x]) {
node->son[x] = make_shared<Node>();
}
node = node->son[x];
}
node->isEnd = true;
}
/** Returns if the word is in the trie. */
bool search(string word) {
auto node = root;
for (char c : word) {
int x = c - 'a';
if (!node->son[x]) {
return false;
}
node = node->son[x];
}
return node->isEnd == true;
}
/** Returns if there is any word in the trie that starts with the given
* prefix. */
bool startsWith(string prefix) {
auto node = root;
for (char c : prefix) {
int x = c - 'a';
if (!node->son[x]) {
return false;
}
node = node->son[x];
}
return true;
}
};
模板二
优点:节约new的时间
#include <bits/stdc++.h>
using namespace std;
#define N 100010
int son[N][26], cnt[N], idx;
// 0号点既是根节点,又是空节点
// son[][]存储树中每个节点的子节点
// 一维表示当前节点编号,二维表示儿子节点的下标
// cnt[]存储以每个节点结尾的单词数量
// ide为当前最大节点索引
// 插入一个字符串
void insert(const string& str) {
int p = 0, n = str.size();
for (int i = 0; i < n; i++) {
int u = str[i] - 'a';
if (!son[p][u])
son[p][u] = ++idx;
p = son[p][u];
}
cnt[p]++;
}
// 查询字符串出现的次数
int query(const string& str) {
int p = 0, n = str.size();
for (int i = 0; i < n; i++) {
int u = str[i] - 'a';
if (!son[p][u])
return 0;
p = son[p][u];
}
return cnt[p];
}
int main() {
insert("abcd");
insert("abcd");
cout << query("abc") << endl;
cout << query("abcd") << endl;
getchar();
}