Description
Two strings X and Y are similar if we can swap two letters (in different positions) of X, so that it equals Y. Also two strings X and Y are similar if they are equal.
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 strs of strings where every string in strs is an anagram of every other string in strs. How many groups are there?
Examples
Example 1:
Input: strs = [“tars”,“rats”,“arts”,“star”]
Output: 2
Example 2:
Input: strs = [“omv”,“ovm”]
Output: 1
Constraints:
1 <= strs.length <= 300
1 <= strs[i].length <= 300
strs[i] consists of lowercase letters only.
All words in strs have the same length and are anagrams of each other.
思路
我用的是judgeSimiliar+bfs
要注意的是我一开始的judgeSimiliar判断了两个单词是否为“swap”,后面发现不用,constraints里面的anagram我不太理解意思,但实际应用下来发现只要统计两个单词的“不同字符个数”<=2即可
另:有看到用并查集的,下次再关心一下
代码
class Solution {
// first way(judge "swap")
public boolean isSimiliar2(String a, String b) {
if (a.equals(b))
return true;
int i = 0;
for (i = 0; i < a.length(); i++) {
if (a.charAt(i) != b.charAt(i))
break;
}
char tmpA = a.charAt(i);
char tmpB = b.charAt(i);
for(i = i + 1; i < a.length(); i++) {
if (a.charAt(i) != b.charAt(i))
break;
}
if (i == a.length())
return false;
if (tmpA != b.charAt(i) || tmpB != a.charAt(i))
return false;
if (i == a.length() - 1)
return true;
return a.substring(i + 1).equals(b.substring(i + 1));
}
// second way(judge counts)
public boolean isSimiliar(String a, String b) {
int count = 0;
for (int i = 0; i < a.length(); i++) {
if (a.charAt(i) != b.charAt(i))
count += 1;
if (count > 2)
return false;
}
return true;
}
public int numSimilarGroups(String[] strs) {
int[][] adj = new int[strs.length][strs.length];
for(int i = 0; i < strs.length; i++){
adj[i][i] = 1;
for(int j = i + 1; j < strs.length; j++){
int isAdj = isSimiliar(strs[i], strs[j])? 1: 0;
adj[i][j] = isAdj;
adj[j][i] = isAdj;
}
}
int groupCount = 0;
int[] visited = new int[strs.length];
for (int i = 0; i < strs.length; i++) {
if (visited[i] == 1)
continue;
List<Integer> neighbors = new ArrayList<>();
neighbors.add(i);
while(neighbors.size() > 0) {
int curr = neighbors.get(0);
for (int j = 0; j < strs.length; j++) {
if (adj[curr][j] == 1 && visited[j] == 0){
visited[j] = 1;
neighbors.add(j);
}
}
neighbors.remove(0);
}
groupCount += 1;
}
return groupCount;
}
}