题目来源:力扣(LeetCode)https://leetcode-cn.com/problems/satisfiability-of-equality-equationspython
给定一个由表示变量之间关系的字符串方程组成的数组,每一个字符串方程 equations[i] 的长度为 4,并采用两种不一样的形式之一:"a==b" 或 "a!=b"。在这里,a 和 b 是小写字母(不必定不一样),表示单字母变量名。算法
只有当能够将整数分配给变量名,以便知足全部给定的方程时才返回 true,不然返回 false。数组
示例 1:bash
输入:["a==b","b!=a"] 输出:false 解释:若是咱们指定,a = 1 且 b = 1,那么能够知足第一个方程,但没法知足第二个方程。没有办法分配变量同时知足这两个方程。
示例 2:微信
输出:["b==a","a==b"] 输入:true 解释:咱们能够指定 a = 1 且 b = 1 以知足知足这两个方程。
示例 3:spa
输入:["a==b","b==c","a==c"] 输出:true
示例 4:设计
输入:["a==b","b!=c","c==a"] 输出:false
示例 5:code
输入:["c==c","b==d","x!=z"] 输出:true
提示:blog
思路:并查集leetcode
先看例 3 和 例 4。这两个例题中,所给不一样部分就是数组中第二个方程式。看看例 4 中,为什么返回的结果是 False?
["a==b","b!=c","c==a"]
在例 4 当中,第二个式子 b!=c
,而前面的式子中 a==c
那么这里将 a
替换 b
,第二个式子就变为 a!=c
,可是最后的式子中 a==c
又成立,这里就明显存在冲突,因此这里结果返回 False。
在上面的例子当中,咱们也能够看到,相等关系具备传递性,全部的相等变量实际上是属于同一个集合。可是这里并不关心传递的距离,只关心是否连通。那么这里就考虑使用并查集来解决本问题。
这里,关于并查集设计算法具体以下:
这里还须要再次遍历全部不等式,由于不等式的两个变量不属于同一个连通份量,这里二者不能合并,要分开查找对应的连通份量,这里有两种状况:
在这里,咱们能够将数组中方程式的变量当成节点,相等关系则表示两个节点的边。前面说明,相等变量属于同个连通份量,那么使用并查集来维护这个关系
具体的实现:
具体的代码实现以下。
from typing import List class Solution: # 并查集类 class UnionFind(object): def __init__(self): '''初始化数组 ''' self.parent = list(range(26)) def find(self, index): '''查询操做 查询直至根节点 这里使用了路径压缩 ''' # 若是父节点是自身,那么就是根节点,返回 while index!=self.parent[index]: self.parent[index] = self.parent[self.parent[index]] index = self.parent[index] return index def union(self, index1, index2): '''合并操做 将其中一个变量的根节点指向另一个变量的根节点 ''' root_index1 = self.find(index1) root_index2 = self.find(index2) self.parent[root_index1] = root_index2 def is_connected(self, index1, index2): '''判断是否连通 ''' return self.find(index1) == self.find(index2) def equationsPossible(self, equations: List[str]) -> bool: uf = Solution.UnionFind() # 第一次遍历全部等式,进行合并 for equation in equations: if equation[1] == "=": # 这里将变量字符转换为整数 # ord('a') 返回对应的十进制整数 index1 = ord(equation[0]) - ord('a') index2 = ord(equation[3]) - ord('a') uf.union(index1, index2) # 再次遍历全部不等式,查找对应的连通份量 for equation in equations: if equation[1] == '!': index1 = ord(equation[0]) - ord('a') index2 = ord(equation[3]) - ord('a') # 若是两个变量属于同个连通份量,那就出现矛盾,返回 False if uf.is_connected(index1, index2): return False # 最终没有矛盾,返回 True return True # equations = ["b==a","a==b"] equations = ["a==b","b!=a"] solution = Solution() solution.equationsPossible(equations)
关于并查集的算法设计流程:
以上就是关于解决《990. 等式方程的可知足性》问题的主要内容。若是以为写得还不错,欢迎关注。微信公众号《书所集录》同步更新,一样欢迎关注。