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]; };