intfind(int x){ return f[x] == x ? x : f[x] = find(f[x]); }
boolcheck(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) { returnfalse; } } } returntrue; }
intnumSimilarGroups(vector<string> &strs){ int n = strs.size(); int m = strs[0].length(); 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; } if (check(strs[i], strs[j], m)) { f[fi] = fj; } } } int ret = 0; for (int i = 0; i < n; i++) { if (f[i] == i) { ret++; } } return ret; } };
classSolution: defnumSimilarGroups(self, strs: List[str]) -> int: n = len(strs) f = list(range(n))
deffind(x: int) -> int: if f[x] == x: return x f[x] = find(f[x]) return f[x] defcheck(a: str, b: str) -> bool: num = 0 for ac, bc inzip(a, b): if ac != bc: num += 1 if num > 2: returnFalse returnTrue for i inrange(n): for j inrange(i + 1, n): fi, fj = find(i), find(j) if fi == fj: continue if check(strs[i], strs[j]): f[fi] = fj ret = sum(1for i inrange(n) if f[i] == i) return ret
intfind(int *f, int x) { return f[x] == x ? x : (f[x] = find(f, f[x])); }
boolcheck(char *a, char *b, int len) { int num = 0; for (int i = 0; i < len; i++) { if (a[i] != b[i]) { num++; if (num > 2) { returnfalse; } } } returntrue; }
intnumSimilarGroups(char **strs, int strsSize) { int n = strsSize; int m = strlen(strs[0]); int f[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(f, i), fj = find(f, j); if (fi == fj) { continue; } if (check(strs[i], strs[j], m)) { f[fi] = fj; } } } int ret = 0; for (int i = 0; i < n; i++) { if (f[i] == i) { ret++; } } return ret; }
复杂度分析
时间复杂度:O(n^2m + n \log n)),其中 n 是字符串的数量。我们需要 O(n^2) 地枚举任意一对字符串之间的关系,对于任意一对字符串,我们需要 O(m) 的时间检查字符串是否相同。在最坏情况下我们需要对并查集执行 O(n) 次合并,合并的均摊时间复杂度 O(\log n)。综上,总的时间复杂度为 O(n^2m + n \log n))。