
方法并查集:
- 我们可以将每一个变量看作图中的一个节点,把相等的关系 == 看作是连接两个节点的边,那么由于表示相等关系的等式方程具有传递性,即如果
a==b 和 b==c 成立,则 a==c 也成立。也就是说,所有相等的变量属于同一个连通分量。因此,我们可以使用并查集来维护这种连通分量的关系。
- 所以首先遍历所有等式,构造并查集,同一个等式中的两个变量属于同一个连通分量,因此将两个变量进行合并
- 然后遍历所有的不等式。同一个不等式中的两个变量不能属于同一个连通分量,因此对两个变量分别查找其所在的连通分量,如果两个变量在同一个连通分量中,则产生矛盾,返回
false。
- 如果遍历完所有的不等式没有发现矛盾,则返回
true。
代码:
- parent切片,其下标
0~25代表变量a~z,下标所对应的值代表其父节点是哪一个节点
- 第一个for循环,初始化parent切片,使每一个下标所对应的值等于其下标,也就是说这些节点的父节点是自己,即这26个字母互不关联
- 遍历所有等式,使原来互不关联的26个元素,产生关系,union函数所做的便是如此,就是使index1的根节点(其实就是父节点的父节点一直往后找,直到找到最终的节点,而这个过程由find函数来完成)的父节点指向,指向index2的根节点,让这两个元素产生关联
- 经过遍历所有的等式,所构造完成的并查集parent就是这26个元素之间的关系
- 最后遍历所有不等式,查看他们各自的根节点是否相同,如果相同则便是这两个元素存在相当的关系,不等式自然不成立,返回
false
- 如果全都符合,则返回
true
func equationsPossible(equations []string) bool {
parent := make([]int,26)
for i := range parent {
parent[i] = i
}
for _,v := range equations {
if v[1] == '=' {
index1 := int(v[0] - 'a')
index2 := int(v[3] - 'a')
union(parent, index1, index2)
}
}
for _,v := range equations {
if v[1] == '!' {
index1 := int(v[0] - 'a')
index2 := int(v[3] - 'a')
if find(parent, index1) == find(parent, index2) {
return false
}
}
}
return true
}
func union (parent []int, index1,index2 int) {
parent[find(parent, index1)] = find(parent, index2)
}
func find (parent []int, index int) int {
for parent[index] != index {
parent[index] = parent[parent[index]]
index = parent[index]
}
return index
}