按字典序排列最小的等效字符串
难度:
标签:
题目描述
代码结果
运行时间: 31 ms, 内存: 16.1 MB
/*
题目思路:
1. 使用并查集(Union-Find)算法来管理字符之间的等价关系。
2. 初始化每个字符自己和自己等价。
3. 遍历 s1 和 s2,将对应字符进行合并。
4. 查找每个字符的最小等价字符,并用其替换 baseStr 中的字符。
5. 返回替换后的字符串。
*/
import java.util.stream.IntStream;
public class Solution {
private int find(int[] parent, int index) {
if (parent[index] != index) {
parent[index] = find(parent, parent[index]);
}
return parent[index];
}
private void union(int[] parent, int index1, int index2) {
int root1 = find(parent, index1);
int root2 = find(parent, index2);
if (root1 != root2) {
if (root1 < root2) {
parent[root2] = root1;
} else {
parent[root1] = root2;
}
}
}
public String smallestEquivalentString(String s1, String s2, String baseStr) {
int[] parent = IntStream.range(0, 26).toArray();
IntStream.range(0, s1.length()).forEach(i -> union(parent, s1.charAt(i) - 'a', s2.charAt(i) - 'a'));
return baseStr.chars()
.mapToObj(c -> String.valueOf((char) (find(parent, c - 'a') + 'a')))
.collect(Collectors.joining());
}
}
解释
方法:
本题使用并查集(Union-Find)数据结构来解决字符等价的问题。并查集是一种有效管理元素分组关系的数据结构,特别适合处理动态连通性问题。首先,初始化一个大小为26的并查集,代表26个英文字母。遍历s1和s2中的字符,将每对等价字符联合在一起。这样,所有传递性等价的字符都会被归入同一个集合。在处理完所有等价关系后,对于baseStr中的每个字符,查找其所属的集合代表(即最小字典序的字符),并构建最终的结果字符串。
时间复杂度:
O(n + m)
空间复杂度:
O(1)
代码细节讲解
🦆
在并查集的实现中,如何确保在union操作时总是将字典序较小的字符作为代表?
▷🦆
对于多个等价类交叉的情况,例如'A == B', 'B == C', 'A == D', 并查集是如何处理这种复杂的传递性关系的?
▷🦆
在并查集中使用路径压缩优化find操作时,是否会影响union操作的效率,以及如何在union时保持路径压缩的效果?
▷🦆
解题方法中是否考虑了所有字符都是自反性的情况,即baseStr中的字符在s1和s2中没有出现,这种情况下算法是否仍然有效?
▷