839. 相似字符串组 - 力扣(LeetCode)
学习打板并查集
安照oi-wiki的说法来说的话,并查集就是按照其字面意思 ,合并与查询,并查集在经过修改后可以支持单个元素的删除、移动;
当然学并查集是因为我发现自己连树状数组都有些理解不了,所以先来看点更简单的,还是不能一步跨太大,我承认我是废物,看到勿骂;
按照我对这题目意思的理解就是查找联通块的个数,每种相似的构成一种联通快,单独的可作为单独一个联通块;
class Solution {
public:
vector<int> f;int find(int x){while(x != f[x]){x = f[x] = f[f[x]];}return x;
}//板子内容,如果是初始值,直接返回初始值,但此题只会改变fi的值并且不会进行第二遍访问,所以不要考虑不是的情况// int find(int x) {// return f[x] == x ? x : f[x] = find(f[x]);//}另外一种写法bool check(const string &a,const string &b,int len){int num = 0;for(int i = 0;i <= len;i++){if(a[i] != b[i]){num++;if(num > 2) return false;}}return true;
}//检查两个字符串是否相似int numSimilarGroups(vector<string>& strs) {int n = strs.size();int m = strs[0].size();f.resize(n);for(int i = 0;i < n;i++){f[i] = i;}//进行初始的赋值for(int i= 0;i < n;i++){for(int j = i + 1;j < n;j++){int fi = find(i),fj = find(j);if(fi == fj) continue;//fi == fj表示i和j已经指向了一个连通块if(check(strs[i],strs[j],m)) f[fi] = fj;//将fi和fj指向同一个联通块}}int ret = 0;for(int i = 0;i < n;i++){if(f[i] == i) ret++;//fi[i] == i即为联通块的个数}return ret;}
};