給你乙個變數對陣列 equations 和乙個實數值陣列 values 作為已知條件,其中 equations[i] = [ai, bi] 和 values[i] 共同表示等式 ai / bi = values[i] 。每個 ai 或 bi 是乙個表示單個變數的字串。另有一些以陣列 queries 表示的問題,其中 queries[j] = [cj, dj] 表示第 j 個問題,請你根據已知條件找出 cj / dj = ? 的結果作為答案。返回 所有問題的答案 。如果存在某個無法確定的答案,則用 -1.0 替代這個答案。
注意:輸入總是有效的。你可以假設除法運算中不會出現除數為 0 的情況,且不存在任何矛盾的結果。
這道題可以轉化為乙個 帶權圖問題。
a/b = 2, b/c=3 => a/c=6
可以抽象為 a到b的邊權重為2,b到c的邊權重為3, a到c的邊權重為2*3=6,圖中任意2點的距離用2點之間邊的權重乘積表示.
如此,問題歸為,如何求圖中任意兩點的距離,可以使用floyd演算法解決。
class
solution
:def
calcequation
(self, equations: list[list[
str]
], values: list[
float
], queries: list[list[
str]])
-> list[
float]:
from collections import defaultdict
graph=defaultdict(
int)
#graph為乙個字典
set1=
set(
)for i in
range
(len
(equations)):
a,b=equations[i]
graph[
(a,b)
]=values[i]
#獲取頂點(a,b)間邊的權值
graph[
(b,a)]=
1/values[i]
set1.add(a)
set1.add(b)
# floyd演算法,求圖中任意兩點距離
arr=
list
(set1)
#集合轉換為列表
for k in arr:
for i in arr:
for j in arr:
if graph[
(i,k)
]and graph[
(k,j)]:
#若值存在
graph[
(i,j)
]= graph[
(i,k)
]*graph[
(k,j)
]
res=
for x,y in queries:
if graph[
(x,y)]:
(x,y)])
else:-
1)return res
defaultdict
class
unionfind
:def
__init__
(self)
:"""
記錄每個節點的父節點
"""self.father =
deffind
(self,x)
:"""
查詢根節點
路徑壓縮
"""root = x
while self.father[root]
!=none
: root = self.father[root]
# 路徑壓縮
while x != root:
original_father = self.father[x]
self.father[x]
= root
x = original_father
return root
defmerge
(self,x,y,val)
:"""
合併兩個節點
"""root_x,root_y = self.find(x)
,self.find(y)
if root_x != root_y:
self.father[root_x]
= root_y
defis_connected
(self,x,y)
:"""
判斷兩節點是否相連
"""return self.find(x)
== self.find(y)
defadd
(self,x)
:"""
新增新節點
"""if x not
in self.father:
self.father[x]
=none
被除數當作子節點,除數當作父節點
class
unionfind
:def
__init__
(self)
:"""
記錄每個節點的父節點
記錄每個節點到根節點的權重
"""self.father =
self.value =
deffind
(self,x)
:"""
查詢根節點
路徑壓縮
更新權重
"""root = x
# 節點更新權重的時候要放大的倍數
base =
1while self.father[root]
!=none
: root = self.father[root]
base *= self.value[root]
while x != root:
original_father = self.father[x]
##### 離根節點越遠,放大的倍數越高
self.value[x]
*= base
base /= self.value[original_father]
#####
self.father[x]
= root
x = original_father
return root
defmerge
(self,x,y,val)
:"""
合併兩個節點
"""root_x,root_y = self.find(x)
,self.find(y)
if root_x != root_y:
self.father[root_x]
= root_y
##### 四邊形法則更新根節點的權重
self.value[root_x]
= self.value[y]
* val / self.value[x]
defis_connected
(self,x,y)
:"""
兩節點是否相連
"""return x in self.value and y in self.value and self.find(x)
== self.find(y)
defadd
(self,x)
:"""
新增新節點,初始化權重為1.0
"""if x not
in self.father:
self.father[x]
=none
self.value[x]
=1.0
class
solution
:def
calcequation
(self, equations: list[list[
str]
], values: list[
float
], queries: list[list[
str]])
-> list[
float]:
uf = unionfind(
)for
(a,b)
,val in
zip(equations,values)
: uf.add(a)
uf.add(b)
uf.merge(a,b,val)
res =[-
1.0]
*len
(queries)
for i,
(a,b)
inenumerate
(queries)
:if uf.is_connected(a,b)
: res[i]
= uf.value[a]
/ uf.value[b]
return res
399 除法求值
給出方程式a b k,其中a和b均為代表字串的變數,k是乙個浮點型數字。根據已知方程式求解問題,並返回計算結果。如果結果不存在,則返回 1.0。示例 給定a b 2.0,b c 3.0 問題 a c b a a e a a x x 返回 6.0,0.5,1.0,1.0,1.0 輸入為 vector ...
399 除法求值
給出方程式a b k,其中a和b均為用字串表示的變數,k是乙個浮點型數字。根據已知方程式求解問題,並返回計算結果。如果結果不存在,則返回 1.0。輸入總是有效的。你可以假設除法運算中不會出現除數為 0 的情況,且不存在任何矛盾的結果。示例 1 輸入 equations a b b c values ...
399 除法求值
給你乙個變數對陣列 equations 和乙個實數值陣列 values 作為已知條件,其中 equations i ai,bi 和 values i 共同表示等式 ai bi values i 每個 ai 或 bi 是乙個表示單個變數的字串。另有一些以陣列 queries 表示的問題,其中 quer...