839. Similar String Groups #
Problem #
Two strings X and Y are similar if we can swap two letters (in different positions) of X, so that it equals Y.
For example, "tars" and "rats" are similar (swapping at positions 0 and 2), and "rats" and "arts" are similar, but "star" is not similar to "tars", "rats", or "arts".
Together, these form two connected groups by similarity: {"tars", "rats", "arts"} and {"star"}. Notice that "tars" and "arts" are in the same group even though they are not similar. Formally, each group is such that a word is in the group if and only if it is similar to at least one other word in the group.
We are given a list A of strings. Every string in A is an anagram of every other string in A. How many groups are there?
Example 1:
Input: ["tars","rats","arts","star"]
Output: 2
Note:
A.length <= 2000A[i].length <= 1000A.length * A[i].length <= 20000- All words in
Aconsist of lowercase letters only. - All words in
Ahave the same length and are anagrams of each other. - The judging time limit has been increased for this question.
Problem Summary #
If we swap two letters at different positions in string X so that it becomes equal to string Y, then X and Y are called similar strings.
For example, “tars” and “rats” are similar (swap positions 0 and 2); “rats” and “arts” are also similar, but “star” is not similar to “tars”, “rats”, or “arts”.
Together, they form two connected groups by similarity: {“tars”, “rats”, “arts”} and {“star”}. Note that “tars” and “arts” are in the same group even though they are not similar. Formally, for each group, to determine whether a word is in the group, it only needs to be similar to at least one word in that group. We are given a list A of strings without duplicates. Every string in the list is an anagram of every other string in A. How many similar string groups are there in A?
Hints:
- A.length <= 2000
- A[i].length <= 1000
- A.length * A[i].length <= 20000
- All words in A consist of lowercase letters only.
- All words in A have the same length and are anagrams of each other.
- The judging time limit has been increased for this question.
Remark:
- Anagram, a new word formed by changing the positions (order) of the letters of a certain string.
Solution Idea #
- Given a string array, find how many types of “dissimilar” strings there are in this array. The definition of similar strings is: if strings A and B only need one swap of letter positions to become two equal strings, then A and B are similar.
- The solution to this problem is to use Union Find. First, transform the definition of “similar” in the problem: A and B being similar means that A and B have only 2 different characters, and all other characters are equal, so they can become completely equal after one swap. Is it possible that these two characters are still not equal after being swapped? This case does not need to be considered, because the problem states that the given strings are all
anagrams (anagrammeans any permutation and combination of the string). Then this problem becomes relatively simple: we only need to determine whether every two strings are “similar”; if they are similar, performunion(), and finally check how many sets there are in the Union Find.
Code #
package leetcode
import (
"github.com/halfrost/leetcode-go/template"
)
func numSimilarGroups(A []string) int {
uf := template.UnionFind{}
uf.Init(len(A))
for i := 0; i < len(A); i++ {
for j := i + 1; j < len(A); j++ {
if isSimilar(A[i], A[j]) {
uf.Union(i, j)
}
}
}
return uf.TotalCount()
}
func isSimilar(a, b string) bool {
var n int
for i := 0; i < len(a); i++ {
if a[i] != b[i] {
n++
if n > 2 {
return false
}
}
}
return true
}