剑指 Offer II 117. 相似的字符串(839. 相似字符串组)

题目:

思路:

【0】这道题看题目的话有可能会出现懵逼状态,这道题其实和 剑指 Offer II 116. 省份数量(547. 省份数量) 很相似。相当于给一个字符串数组,每一个字符就是一个点,如果两字符相似(即交换字符串 X 中的两个不同位置的字母,使得它和字符串 Y 相等),那么就表示它们联通。所有联通的就是一组,那么会有多少个组,与省份数量这道题相对应。

【1】并查集的方式

【2】深度搜索的方式

代码展示:

深度搜索的方式:

//时间5 ms击败99.77%
//内存41.1 MB击败29.33%
class Solution {
    boolean[] visited = null;
    public int numSimilarGroups(String[] strs) {
        int n = strs.length;
        char[][] c = new char[n][];
        for (int i = 0; i < n; i++) {
            c[i] = strs[i].toCharArray();
        }
        // 初始化
        visited = new boolean[n];
        // dfs
        int res = 0;
        for (int i = 0; i < n; i++) {
            if (!visited[i]) {
                dfs(c, i);
                res++;
            }
        }
        return res;
    }

    private void dfs(char[][] c, int index) {
        visited[index] = true;
        for (int i = 0; i < visited.length; i++) {
            if (!visited[i] && similar(c[i],c[index])) {
                dfs(c, i);
            }
        }
    }

    private boolean similar(char[] a, char[] b) {
        int diff = 0;
        for (int i = 0; i < a.length; i++)
            if (a[i] != b[i] && ++diff > 2)
                return false;
        return true;
    }
}

 

 

 

并查集的方式:

//时间9 ms击败98.61%
//内存40.8 MB击败79.68%
//时间复杂度:O(n^2*m + n*logn),其中 n 是字符串的数量。
//我们需要 O(n^2) 地枚举任意一对字符串之间的关系,对于任意一对字符串,我们需要 O(m) 的时间检查字符串是否相同。
//在最坏情况下我们需要对并查集执行 O(n) 次合并,合并的均摊时间复杂度 O(log⁡n)。
//综上,总的时间复杂度为 O(n^2*m + n*logn)。
//空间复杂度:O(n),其中 n 是字符串的数量。并查集需要 O(n) 的空间。
class Solution {
    int[] f;

    public int numSimilarGroups(String[] strs) {
        int n = strs.length;
        int m = strs[0].length();
        f = new int[n];
        for (int i = 0; i < n; i++) {
            f[i] = i;
        }
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                int fi = find(i), fj = find(j);
                if (fi == fj) {
                    continue;
                }
                if (check(strs[i], strs[j], m)) {
                    f[fi] = fj;
                }
            }
        }
        int ret = 0;
        for (int i = 0; i < n; i++) {
            if (f[i] == i) {
                ret++;
            }
        }
        return ret;
    }

    public int find(int x) {
        return f[x] == x ? x : (f[x] = find(f[x]));
    }

    public boolean check(String a, String b, int len) {
        int num = 0;
        for (int i = 0; i < len; i++) {
            if (a.charAt(i) != b.charAt(i)) {
                num++;
                if (num > 2) {
                    return false;
                }
            }
        }
        return true;
    }
}

 

posted @ 2023-04-26 12:18  忧愁的chafry  阅读(15)  评论(0编辑  收藏  举报