題目來源:力扣(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. 等式方程的可知足性》問題的主要內容。若是以爲寫得還不錯,歡迎關注。微信公衆號《書所集錄》同步更新,一樣歡迎關注。