Similar String Groups

Group strings where two differ by exactly one swap — DSU on pairwise similarity.

Hard
Time O(N^2 * L) Space O(N)
LeetCode
5 min read
union-find strings

Problem#

Two strings are “similar” if they are equal, or if you can swap exactly two positions in one to make them equal. Given a list of anagrams, return the number of similarity groups (transitively closed).

Examples#

  • strs = ["tars","rats","arts","star"]2.
  • strs = ["omv","ovm"]1.

Constraints#

  • 1 <= strs.length <= 300, 1 <= strs[i].length <= 300.

Hints#

Hint
For each pair (i, j), count mismatch positions — similar iff 0 or 2 mismatches.

Approach#

DSU over string indices. For each pair (i, j), count differing positions; if 0 or 2, union. Answer is the count of distinct roots.

Solution#

Similar String Groups
class Solution {
vector<int> parent;
int find(int x) { while (parent[x] != x) { parent[x] = parent[parent[x]]; x = parent[x]; } return x; }
void unite(int a, int b) { parent[find(a)] = find(b); }
public:
int numSimilarGroups(vector<string>& strs) {
int n = strs.size();
parent.resize(n);
iota(parent.begin(), parent.end(), 0);
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
if (find(i) == find(j)) continue;
int diff = 0;
for (int k = 0; k < (int)strs[i].size() && diff <= 2; ++k)
if (strs[i][k] != strs[j][k]) ++diff;
if (diff == 0 || diff == 2) unite(i, j);
}
}
int groups = 0;
for (int i = 0; i < n; ++i) if (find(i) == i) ++groups;
return groups;
}
};

Editorial#

For each pair, we early-exit the character comparison once diff > 2 — strings are similar only at exactly 0 or 2 mismatches. The pre-union check find(i) == find(j) short-circuits already-unioned pairs. When N^2 * L < N * 26^L we compare pairs directly; otherwise generate all single-swap neighbors per string and look up in a hash map.

Complexity#

  • Time: O(N^2 * L).
  • Space: O(N).

Concept revision#

Search ESC

Keyboard shortcuts

Shortcuts are disabled while typing in inputs.