399 除法求值

2021-10-14 03:55:39 字數 4523 閱讀 3884

給你乙個變數對陣列 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...