leetcode 困难 —— 相似字符串组(并查集)

题目:
如果交换字符串 X 中的两个不同位置的字母,使得它和字符串 Y 相等,那么称 X 和 Y 两个字符串相似。如果这两个字符串本身是相等的,那它们也是相似的。
例如,“tars” 和 “rats” 是相似的 (交换 0 与 2 的位置); “rats” 和 “arts” 也是相似的,但是 “star” 不与 “tars”,“rats”,或 “arts” 相似。
总之,它们通过相似性形成了两个关联组:{“tars”, “rats”, “arts”} 和 {“star”}。注意,“tars” 和 “arts” 是在同一组中,即使它们并不相似。形式上,对每个组而言,要确定一个单词在组中,只需要这个词和该组中至少一个单词相似。
给你一个字符串列表 strs。列表中的每个字符串都是 strs 中其它所有字符串的一个字母异位词。请问 strs 中有多少个相似字符串组?

题解:
很简单的思路,就是一个并查集模板题

判断每两个字符串之间,如果相似或者相同,就并在一组
最后判断有多少组,即可

(最开始还以为并查集复杂度是 logn,一直以为 n * n * n * logn 超时了,想半天怎么快速比对两字符串,后面才发现,原来并查集复杂度是 O(α(n)),α(n) 不会超过 5,就近似于 O(1),所以不超时)

代码如下:

class Solution {
public:
    int flag[305];
    bool f[305];
    int res;
    bool test(string a, string b) {
        int flag = 0;
        for(int i = 0; i < a.size(); i++) {
            if(a[i] != b[i]) flag++;
        }
        if(flag == 2 || flag == 0) return true;
        else return false;
    }
    int find(int x) {
        if(x == flag[x])
            return x;
        else{
            return flag[x] = find(flag[x]);
        }
    }
    void merge(int i, int j)
    {
        flag[find(i)] = find(j);
    }
    int numSimilarGroups(vector<string>& strs) {
        for(int i = 0; i < strs.size(); i++) {
            flag[i] = i;
        }
        for(int i = 0; i < strs.size(); i++) {
            for(int j = i + 1; j < strs.size(); j++) {
                if(test(strs[i], strs[j])) {
                    merge(i, j);
                }
            }
        }
        for(int i = 0; i < strs.size(); i++) {
            int p = find(i);
            if(f[p] == false) {
                f[p] = true;
                res++;
            }
        }
        return res;
    }
};

猜你喜欢

转载自blog.csdn.net/m0_52212261/article/details/129347156