Skip to content

Commit db16ed7

Browse files
committed
Add solution #839
1 parent 60754b4 commit db16ed7

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,7 @@
646646
836|[Rectangle Overlap](./0836-rectangle-overlap.js)|Easy|
647647
837|[New 21 Game](./0837-new-21-game.js)|Medium|
648648
838|[Push Dominoes](./0838-push-dominoes.js)|Medium|
649+
839|[Similar String Groups](./0839-similar-string-groups.js)|Hard|
649650
841|[Keys and Rooms](./0841-keys-and-rooms.js)|Medium|
650651
844|[Backspace String Compare](./0844-backspace-string-compare.js)|Easy|
651652
846|[Hand of Straights](./0846-hand-of-straights.js)|Medium|
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/**
2+
* 839. Similar String Groups
3+
* https://leetcode.com/problems/similar-string-groups/
4+
* Difficulty: Hard
5+
*
6+
* Two strings, X and Y, are considered similar if either they are identical or we can make them
7+
* equivalent by swapping at most two letters (in distinct positions) within the string X.
8+
*
9+
* For example, "tars" and "rats" are similar (swapping at positions 0 and 2), and "rats" and
10+
* "arts" are similar, but "star" is not similar to "tars", "rats", or "arts".
11+
*
12+
* Together, these form two connected groups by similarity: {"tars", "rats", "arts"} and {"star"}.
13+
* Notice that "tars" and "arts" are in the same group even though they are not similar. Formally,
14+
* each group is such that a word is in the group if and only if it is similar to at least one
15+
* other word in the group.
16+
*
17+
* We are given a list strs of strings where every string in strs is an anagram of every other
18+
* string in strs. How many groups are there?
19+
*/
20+
21+
/**
22+
* @param {string[]} strs
23+
* @return {number}
24+
*/
25+
var numSimilarGroups = function(strs) {
26+
const parent = Array.from({ length: strs.length }, (_, i) => i);
27+
const rank = new Array(strs.length).fill(0);
28+
29+
for (let i = 0; i < strs.length; i++) {
30+
for (let j = i + 1; j < strs.length; j++) {
31+
if (areSimilar(strs[i], strs[j])) union(i, j);
32+
}
33+
}
34+
35+
const groups = new Set();
36+
for (let i = 0; i < strs.length; i++) groups.add(find(i));
37+
38+
return groups.size;
39+
40+
function find(x) {
41+
if (parent[x] !== x) {
42+
parent[x] = find(parent[x]);
43+
}
44+
return parent[x];
45+
}
46+
47+
function union(x, y) {
48+
const rootX = find(x);
49+
const rootY = find(y);
50+
51+
if (rootX === rootY) return;
52+
53+
if (rank[rootX] < rank[rootY]) {
54+
parent[rootX] = rootY;
55+
} else {
56+
parent[rootY] = rootX;
57+
if (rank[rootX] === rank[rootY]) rank[rootX]++;
58+
}
59+
}
60+
61+
function areSimilar(a, b) {
62+
if (a === b) return true;
63+
64+
let diff = 0;
65+
for (let i = 0; i < a.length; i++) {
66+
if (a[i] !== b[i] && ++diff > 2) return false;
67+
}
68+
69+
return diff === 2;
70+
}
71+
};

0 commit comments

Comments
 (0)