Leetcode 839 相似字符数组(并查集)

题目描述:

  如果我们交换字符串 X 中的两个不同位置的字母,使得它和字符串 Y 相等,那么称 X 和 Y 两个字符串相似。如果这两个字符串本身是相等的,那它们也是相似的。例如,"tars" 和 "rats" 是相似的 (交换 0 与 2 的位置); "rats" 和 "arts" 也是相似的,但是 "star" 不与 "tars","rats",或 "arts" 相似。总之,它们通过相似性形成了两个关联组:{"tars", "rats", "arts"} 和 {"star"}。注意,"tars" 和 "arts" 是在同一组中,即使它们并不相似。形式上,对每个组而言,要确定一个单词在组中,只需要这个词和该组中至少一个单词相似。我们给出了一个不包含重复的字符串列表 A。列表中的每个字符串都是 A 中其它所有字符串的一个字母异位词。请问 A 中有多少个相似字符串组?

 

题解:

  相似构图然后并查集判断联通块就好。注意一下连通块的判断方式,判断有几个pre[i] == i就好。

 

AC代码:

  

class Solution {
public:
    bool judege(string a,string b)
    {
        int cnt = 0;
        int Len = a.size();
        for(int i=0;i<Len;i++)
        {
            if(a[i] != b[i]) cnt++;
            if(cnt > 2) return false;
        }
        return cnt <= 2;
    }

    int Find(int x)
    {
        int root = x;
        while(pre[root] != root) root = pre[root];
        while(pre[x] != root)
        {
            int next = pre[x];
            pre[x] = root;
            x = next;
        }
        return root;
    }
    void Merge(int a,int b)
    {
        int aa = Find(a);
        int bb = Find(b);
        if(aa == bb) return;
        pre[aa] = bb;
    }
    
    int numSimilarGroups(vector<string>& A) {
    
        int Len = A.size();
        for(int i=0;i<Len;i++) pre[i] = i;

        for(int i=0;i<Len;i++)
        {
            for(int j=i+1;j<Len;j++)
            {
                if(judege(A[i],A[j])) Merge(i,j);
            }
        }
        
        // 计算根的方式
        int ans = 0;
        for(int i=0;i<Len;i++)
        {
            if(pre[i] == i) ans++;
        }
        return ans;
    }

private:
    int pre[10010];
};

 

posted @ 2020-04-16 11:43  猪突猛进!!!  阅读(252)  评论(0编辑  收藏  举报