Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Similar string groups in JavaScript
Two strings are similar if we can swap exactly two characters at different positions to make them equal, or if they are already equal. Given an array of strings (all anagrams of each other), we need to find how many groups of similar strings exist.
For example, "tars" and "rats" are similar (swap positions 0 and 2), and "rats" and "arts" are similar. This forms one group: {"tars", "rats", "arts"}. The string "star" forms its own group since it's not similar to any other string.
Understanding Similarity
Two strings are similar if:
- They are identical, or
- They differ at exactly 2 positions and swapping those characters makes them equal
Solution Implementation
const arr = ["tars", "rats", "arts", "star"];
const isSimilar = (str1, str2) => {
if (str1 === str2) return true;
let diffCount = 0;
for (let i = 0; i < str1.length; i++) {
if (str1[i] !== str2[i]) {
diffCount++;
}
}
return diffCount === 2;
};
const similarStringGroup = (arr = []) => {
const groups = [[arr[0]]];
for (let i = 1; i < arr.length; i++) {
let matched = false;
for (let j = 0; j < groups.length; j++) {
for (let k = 0; k < groups[j].length; k++) {
if (isSimilar(groups[j][k], arr[i])) {
groups[j].push(arr[i]);
matched = true;
break;
}
}
if (matched) break;
}
if (!matched) {
groups.push([arr[i]]);
}
}
console.log("Groups formed:", groups);
return groups.length;
};
console.log("Number of groups:", similarStringGroup(arr));
Groups formed: [ [ 'tars', 'rats', 'arts' ], [ 'star' ] ] Number of groups: 2
How It Works
The algorithm uses a greedy approach:
- isSimilar function: Checks if two strings are similar by counting character differences
- Group formation: Iterates through each string and tries to place it in an existing group
- New group creation: If a string doesn't fit any existing group, creates a new group
Alternative Approach Using Union-Find
function similarStringGroupsUnionFind(strs) {
const n = strs.length;
const parent = Array.from({length: n}, (_, i) => i);
function find(x) {
if (parent[x] !== x) {
parent[x] = find(parent[x]);
}
return parent[x];
}
function union(x, y) {
const rootX = find(x);
const rootY = find(y);
if (rootX !== rootY) {
parent[rootX] = rootY;
}
}
function areSimilar(s1, s2) {
if (s1 === s2) return true;
let diff = 0;
for (let i = 0; i < s1.length; i++) {
if (s1[i] !== s2[i]) diff++;
if (diff > 2) return false;
}
return diff === 2;
}
// Connect similar strings
for (let i = 0; i < n; i++) {
for (let j = i + 1; j < n; j++) {
if (areSimilar(strs[i], strs[j])) {
union(i, j);
}
}
}
// Count unique groups
const roots = new Set();
for (let i = 0; i < n; i++) {
roots.add(find(i));
}
return roots.size;
}
const testArray = ["tars", "rats", "arts", "star"];
console.log("Groups using Union-Find:", similarStringGroupsUnionFind(testArray));
Groups using Union-Find: 2
Comparison
| Approach | Time Complexity | Space Complexity | Best For |
|---|---|---|---|
| Greedy Grouping | O(n² × m) | O(n) | Small datasets |
| Union-Find | O(n² × m) | O(n) | Better for larger datasets |
Where n is the number of strings and m is the length of each string.
Conclusion
The similar string groups problem uses graph connectivity concepts where strings are nodes and similarity defines edges. Both greedy and Union-Find approaches effectively solve this problem, with Union-Find being more scalable for larger datasets.
