leetcode 839. 相似字符串组

题目在这
困难题看似很复杂,想一想就是图求连通个数
一眼就是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;
    }

仅仅是将字符串转换为数组,效率差了很多…改天研究一下,因为我之前某道题转换为数组明明比字符串处理要快的多

要找实习了,收收心看书了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值