leetcode—839. 相似字符串组

如果交换字符串 X 中的两个不同位置的字母,使得它和字符串 Y 相等,那么称 X 和 Y 两个字符串相似。如果这两个字符串本身是相等的,那它们也是相似的。

例如,"tars" 和 "rats" 是相似的 (交换 0 与 2 的位置); "rats" 和 "arts" 也是相似的,但是 "star" 不与 "tars","rats",或 "arts" 相似。

总之,它们通过相似性形成了两个关联组:{"tars", "rats", "arts"} 和 {"star"}。注意,"tars" 和 "arts" 是在同一组中,即使它们并不相似。形式上,对每个组而言,要确定一个单词在组中,只需要这个词和该组中至少一个单词相似。

给你一个字符串列表 strs。列表中的每个字符串都是 strs 中其它所有字符串的一个字母异位词。请问 strs 中有多少个相似字符串组?

示例 1:

输入:strs = ["tars","rats","arts","star"]
输出:2

分析:

首先解决两个字符串是否相似的问题,由于给出的字符串互相是字母异位词,所以只需要判定字符串相同位置为不同字符的数目,若为0或2则两个字符串相似,否则一定不相似。

然后对给出的字符串数组进行俩俩比对,若字符串相似,则在并查集中将这两个字符串进行合并,合并后这两个字符串的根字符串一致代表他们在同一组关系中。求相似字符串组即求并查集中不同合并关系的数目。

class Solution {
    int[] pre;
    int find(int x){
        while(x != pre[x]){
            x = pre[x];
        }
        return x;
    }
    void union(int x, int y){
        int x1 = find(x);//x的根,即祖先赋值给x1  
        int y1 = find(y);//y的根,即祖先赋值给y1
        //如果两个不属于同一个根,即两个人不是一个祖宗,比如一个姓朱,一个姓李 
       //姓朱的和姓李的不可能是一个祖先吧,但是这两家又产生了关系,比如联姻 
      //例如姓朱的男青年和姓李的黄花大闺女结婚了
 	 //在古代的时候,”嫁鸡随鸡嫁狗随狗“女性是要跟随丈夫的姓氏,所以李姓闺女就要叫做”朱氏“ 
        if(x1 != y1){
            pre[x1] = y1;
        }

    }

//以上为并查集模板

     public int numSimilarGroups(String[] strs) {
        int n = strs.length;
        pre = new int[n];
        for(int i = 0; i < n; i++) pre[i] = i;//初始化
        for(int i = 0; i < n; i++){
            for(int j = i + 1; j < n; j++){
                if(check(strs[i], strs[j])){//检查两个字符串是否是相似关系
                    union(i, j);
                }
            }
        }
        int res = 0;
        for(int i = 0; i < n; i++){
            if(pre[i] == i) 
            res++;
        }
        return res;
    }
    boolean check(String a, String b){
        int cnt = 0;
        int n = a.length();
        for(int i = 0; i < n; i++){
            if(a.charAt(i) != b.charAt(i)) 
            cnt ++;
        }
        return cnt <= 2;
    }
}

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值