题目在这
困难题看似很复杂,想一想就是图求连通个数
一眼就是dfs,第二眼是并查集
dfs
直接击败100%,吓到了
class Solution {
public int numSimilarGroups(String[] strs) {
int n=strs.length;
boolean[]visited=new boolean[n];
int res=0;
for(int i=0;i<n;++i){
if(!visited[i]){
res++;
dfs(strs,i,visited);
}
}
return res;
}
private void dfs(String[]strs,int i,boolean[]visited){
visited[i]=true;
for(int j=0;j<strs.length;++j){
if(!visited[j]&&isValid(strs[i],strs[j])){
dfs(strs,j,visited);
}
}
}
private boolean isValid(String A,String B){
int count=0;
for(int i=0;i<A.length();++i){
if(A.charAt(i)!=B.charAt(i))
count++;
if(count>2)
return false;
}
return true;
}
}
并查集
class Solution {
public int numSimilarGroups(String[] strs) {
int n=strs.length;
UnionFindSet ufs=new UnionFindSet(n);
for(int i=0;i<n-1;++i){
for(int j=i+1;j<n;++j){
if(ufs.find(i)==ufs.find(j))
continue;
if(isValid(strs[i],strs[j]))
ufs.union(i,j);
}
}
return ufs.size;
}
private boolean isValid(String A,String B){
int count=0;
for(int i=0;i<A.length();++i){
if(A.charAt(i)!=B.charAt(i))
count++;
if(count>2)
return false;
}
return true;
}
}
class UnionFindSet{
int []father;
int[]rank;
int size;
public UnionFindSet(int n){
father=new int[n];
rank=new int[n];
for(int i=0;i<n;++i){
father[i]=i;
size++;
}
}
public int find(int x){
int root=x;
while(root!=father[root]){
root=father[root];
}
while(father[x]!=root){
int f=father[x];
father[x]=root;
x=f;
}
return root;
}
public void union(int x,int y){
int fX=find(x);
int fY=find(y);
if(fX!=fY){
if(rank[fX]<rank[fY]){
father[fX]=fY;
}else{
father[fY]=fX;
if(rank[fX]==rank[fY])
rank[fX]++;
}
size--;
}
}
}
吐个槽,一开始我的isValid()函数是这么写的:
private boolean isValid(String A,String B){
char []chA=A.toCharArray();
char []chB=B.toCharArray();
int count=0;
for(int i=0;i<chA.length;++i){
if(chA[i]!=chB[i])
count++;
if(count>2)
return false;
}
return true;
}
仅仅是将字符串转换为数组,效率差了很多…改天研究一下,因为我之前某道题转换为数组明明比字符串处理要快的多
要找实习了,收收心看书了