LeetCode Solutions
839. Similar String Groups
Time: $O(nk \cdot \min(n, k))$, where $n = |\texttt{A}|$ and $k = |\texttt{A[0]}|$ Space: $O(n)$
class Solution {
public:
int numSimilarGroups(vector<string>& A) {
int ans = 0;
vector<bool> seen(A.size());
for (int i = 0; i < A.size(); ++i)
if (!seen[i]) {
dfs(A, i, seen);
++ans;
}
return ans;
}
private:
// Dfs on string A[i]
void dfs(const vector<string>& A, int i, vector<bool>& seen) {
seen[i] = true;
for (int j = 0; j < A.size(); ++j)
if (!seen[j] && isSimilar(A[i], A[j]))
dfs(A, j, seen);
}
bool isSimilar(const string& X, const string& Y) {
int diff = 0;
for (int i = 0; i < X.length(); ++i)
if (X[i] != Y[i] && ++diff > 2)
return false;
return true;
}
};
class Solution {
public int numSimilarGroups(String[] A) {
int ans = 0;
boolean[] seen = new boolean[A.length];
for (int i = 0; i < A.length; ++i)
if (!seen[i]) {
dfs(A, i, seen);
++ans;
}
return ans;
}
private void dfs(final String[] A, int i, boolean[] seen) {
seen[i] = true;
for (int j = 0; j < A.length; ++j)
if (!seen[j] && isSimilar(A[i], A[j]))
dfs(A, j, seen);
}
private boolean isSimilar(final String X, final String Y) {
int diff = 0;
for (int i = 0; i < X.length(); ++i)
if (X.charAt(i) != Y.charAt(i) && ++diff > 2)
return false;
return true;
}
}
class UnionFind {
public:
UnionFind(int n) : count(n), id(n) {
iota(begin(id), end(id), 0);
}
void union_(int u, int v) {
const int i = find(u);
const int j = find(v);
if (i == j)
return;
id[i] = j;
--count;
}
int getCount() const {
return count;
}
private:
int count;
vector<int> id;
int find(int u) {
return id[u] == u ? u : id[u] = find(id[u]);
}
};
class Solution {
public:
int numSimilarGroups(vector<string>& A) {
UnionFind uf(A.size());
for (int i = 1; i < A.size(); ++i)
for (int j = 0; j < i; ++j)
if (isSimilar(A[i], A[j]))
uf.union_(i, j);
return uf.getCount();
}
private:
bool isSimilar(const string& X, const string& Y) {
int diff = 0;
for (int i = 0; i < X.length(); ++i)
if (X[i] != Y[i] && ++diff > 2)
return false;
return true;
}
};