字符串归类 并查集

4304. 字符串归类

给定 n 个由小写字母构成的字符串。

现在,请你对它们进行归类。

对于两个字符串 a 和 b:

  • 如果至少存在一个字母在 a 和 b 中同时出现,则 a 和 b 属于同一类字符串。
  • 如果字符串 c 既与字符串 a 同类,又与字符串 b 同类,则 a 和 b 属于同一类字符串。

请问,最终所有字符串被划分为多少类。

输入格式

第一行包含整数 n。

接下来 n 行,每行包含一个仅由小写字母构成的字符串。

注意,输入字符串可能相同。

输出格式

一个整数,表示最终所有字符串被划分为的类的数量。

数据范围

前 6 个测试点满足 1≤n≤10。
所有测试点满足 1≤n≤2×105,输入字符串的长度范围 [1,50],所有输入字符串的总长度范围 [1,106],所有字符串均由小写英文字母构成。

输入样例1:

4
a
b
ab
d

输出样例1:

2

输入样例2:

3
ab
bc
abc

输出样例2:

1

输入样例3:

1
abcdefghijklmn

输出样例3:

1

思路

st数组标记字符是否出现过,利用并查集进行归类

代码

#include<iostream>

using namespace std;
const int N = 27;
int n, res, p[N];
bool st[N];

int find(int x) {
    if (x != p[x]) p[x] = find(p[x]);
    return p[x];
}

int main() {
    cin >> n;
    string s;
    for (int i = 0; i < N; ++i) p[i] = i;
    for (int i = 0; i < n; ++i) {
        cin >> s;
        int t = find(s[0] - 'a');
        st[s[0] - 'a'] = true;
        for (int j = 1; j < s.length(); ++j) {
            p[find(s[j] - 'a')] = t;
            st[s[j] - 'a'] = true;
        }
    }
    for (int i = 0; i < N; ++i)
        // 出现过的每一类都只有一个成员满足p[i] == i
        if (st[i] && p[i] == i)
            res++;
    cout << res << endl;
    return 0;
}
posted @   嘿,抬头!  阅读(50)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
点击右上角即可分享
微信分享提示