识海社区打卡-5

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;
    }
};
posted @ 2024-11-16 19:39  夏尾草  阅读(8)  评论(0)    收藏  举报