剑指 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(logn)。 //综上,总的时间复杂度为 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; } }