Skip to content

Commit 8e80f33

Browse files
committed
bfs dfs 399
1 parent 9709728 commit 8e80f33

File tree

2 files changed

+249
-0
lines changed

2 files changed

+249
-0
lines changed

go/bfs-dfs/399/399.除法求值.go

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
/*
2+
* @lc app=leetcode.cn id=399 lang=golang
3+
*
4+
* [399] 除法求值
5+
*
6+
* https://leetcode.cn/problems/evaluate-division/description/
7+
*
8+
- algorithms
9+
- Medium (59.00%)
10+
- Likes: 1043
11+
- Dislikes: 0
12+
- Total Accepted: 86.7K
13+
- Total Submissions: 147.1K
14+
- Testcase Example: '[["a","b"],["b","c"]]\n' +
15+
'[2.0,3.0]\n' +
16+
'[["a","c"],["b","a"],["a","e"],["a","a"],["x","x"]]'
17+
18+
*
19+
* 给你一个变量对数组 equations 和一个实数值数组 values 作为已知条件,其中 equations[i] = [Ai, Bi] 和
20+
* values[i] 共同表示等式 Ai / Bi = values[i] 。每个 Ai 或 Bi 是一个表示单个变量的字符串。
21+
*
22+
* 另有一些以数组 queries 表示的问题,其中 queries[j] = [Cj, Dj] 表示第 j 个问题,请你根据已知条件找出 Cj / Dj
23+
* = ? 的结果作为答案。
24+
*
25+
* 返回 所有问题的答案 。如果存在某个无法确定的答案,则用 -1.0 替代这个答案。如果问题中出现了给定的已知条件中没有出现的字符串,也需要用 -1.0
26+
* 替代这个答案。
27+
*
28+
* 注意:输入总是有效的。你可以假设除法运算中不会出现除数为 0 的情况,且不存在任何矛盾的结果。
29+
*
30+
* 注意:未在等式列表中出现的变量是未定义的,因此无法确定它们的答案。
31+
*
32+
*
33+
*
34+
* 示例 1:
35+
*
36+
*
37+
* 输入:equations = [["a","b"],["b","c"]], values = [2.0,3.0], queries =
38+
* [["a","c"],["b","a"],["a","e"],["a","a"],["x","x"]]
39+
* 输出:[6.00000,0.50000,-1.00000,1.00000,-1.00000]
40+
* 解释:
41+
* 条件:a / b = 2.0, b / c = 3.0
42+
* 问题:a / c = ?, b / a = ?, a / e = ?, a / a = ?, x / x = ?
43+
* 结果:[6.0, 0.5, -1.0, 1.0, -1.0 ]
44+
* 注意:x 是未定义的 => -1.0
45+
*
46+
* 示例 2:
47+
*
48+
*
49+
* 输入:equations = [["a","b"],["b","c"],["bc","cd"]], values = [1.5,2.5,5.0],
50+
* queries = [["a","c"],["c","b"],["bc","cd"],["cd","bc"]]
51+
* 输出:[3.75000,0.40000,5.00000,0.20000]
52+
*
53+
*
54+
* 示例 3:
55+
*
56+
*
57+
* 输入:equations = [["a","b"]], values = [0.5], queries =
58+
* [["a","b"],["b","a"],["a","c"],["x","y"]]
59+
* 输出:[0.50000,2.00000,-1.00000,-1.00000]
60+
*
61+
*
62+
*
63+
*
64+
* 提示:
65+
*
66+
*
67+
* 1 <= equations.length <= 20
68+
* equations[i].length == 2
69+
* 1 <= Ai.length, Bi.length <= 5
70+
* values.length == equations.length
71+
* 0.0 < values[i] <= 20.0
72+
* 1 <= queries.length <= 20
73+
* queries[i].length == 2
74+
* 1 <= Cj.length, Dj.length <= 5
75+
* Ai, Bi, Cj, Dj 由小写英文字母与数字组成
76+
*
77+
*
78+
*/
79+
package jzoffer
80+
81+
// @lc code=start
82+
func calcEquation1(equations [][]string, values []float64, queries [][]string) (res []float64) {
83+
// 建图
84+
graph := make(map[string]map[string]float64)
85+
for i, v := range equations {
86+
if _, ok := graph[v[0]]; !ok {
87+
graph[v[0]] = map[string]float64{v[1]: values[i]}
88+
} else {
89+
graph[v[0]][v[1]] = values[i]
90+
}
91+
92+
if _, ok := graph[v[1]]; !ok {
93+
graph[v[1]] = map[string]float64{v[0]: 1 / values[i]}
94+
} else {
95+
graph[v[1]][v[0]] = 1 / values[i]
96+
}
97+
}
98+
res = make([]float64, len(queries))
99+
// dfs 找起点
100+
for i, v := range queries {
101+
// 起点,终点 必须都在图里才有解
102+
nodes0, ok := graph[v[0]]
103+
if !ok {
104+
res[i] = -1.0
105+
continue
106+
}
107+
if _, ok := graph[v[1]]; !ok {
108+
res[i] = -1.0
109+
continue
110+
}
111+
// 都在图里,且相同的 直接返回1
112+
if v[0] == v[1] {
113+
res[i] = 1.0
114+
continue
115+
}
116+
// 在图里有对应的edge
117+
if val, ok := nodes0[v[1]]; ok {
118+
res[i] = val
119+
continue
120+
}
121+
122+
// bfs查找多层的路径,把边的权重带上
123+
type edgeNode struct {
124+
node string
125+
weight float64
126+
}
127+
queue := []edgeNode{}
128+
for k := range nodes0 {
129+
queue = append(queue, edgeNode{k, nodes0[k]})
130+
}
131+
visited := map[string]bool{v[0]: true}
132+
for len(queue) > 0 {
133+
top := queue[len(queue)-1]
134+
queue = queue[:len(queue)-1]
135+
if top.node == v[1] {
136+
res[i] = top.weight
137+
break
138+
}
139+
visited[top.node] = true
140+
for k, kWeight := range graph[top.node] {
141+
if visited[k] {
142+
continue
143+
}
144+
queue = append(queue, edgeNode{k, kWeight * top.weight})
145+
}
146+
}
147+
if res[i] < 0.0000000000000000000001 { // 没有设置过值的0 改成-1
148+
res[i] = -1.0
149+
}
150+
}
151+
return
152+
}
153+
154+
func calcEquation(equations [][]string, values []float64, queries [][]string) (res []float64) {
155+
// 建图
156+
graph := make(map[string]map[string]float64)
157+
for i, v := range equations {
158+
if _, ok := graph[v[0]]; !ok {
159+
graph[v[0]] = map[string]float64{v[1]: values[i]}
160+
} else {
161+
graph[v[0]][v[1]] = values[i]
162+
}
163+
164+
if _, ok := graph[v[1]]; !ok {
165+
graph[v[1]] = map[string]float64{v[0]: 1 / values[i]}
166+
} else {
167+
graph[v[1]][v[0]] = 1 / values[i]
168+
}
169+
}
170+
res = make([]float64, len(queries))
171+
// dfs 找起点
172+
for i, v := range queries {
173+
start, end := v[0], v[1]
174+
nodes0, ok0 := graph[start]
175+
_, ok1 := graph[end]
176+
if !ok0 || !ok1 { // 起点,终点 必须都在图里才有解
177+
res[i] = -1.0
178+
continue
179+
}
180+
if start == end { // 都在图里,且相同的 直接返回1
181+
res[i] = 1.0
182+
continue
183+
}
184+
185+
// bfs查找多层的路径,把边的权重带上
186+
type edgeNode struct {
187+
node string
188+
weight float64
189+
}
190+
queue := []edgeNode{}
191+
for k := range nodes0 {
192+
queue = append(queue, edgeNode{k, nodes0[k]})
193+
}
194+
visited := map[string]bool{start: true}
195+
for len(queue) > 0 {
196+
top := queue[len(queue)-1]
197+
queue = queue[:len(queue)-1]
198+
if top.node == end {
199+
res[i] = top.weight
200+
break
201+
}
202+
visited[top.node] = true
203+
for k, kWeight := range graph[top.node] {
204+
if visited[k] {
205+
continue
206+
}
207+
queue = append(queue, edgeNode{k, kWeight * top.weight})
208+
}
209+
}
210+
if res[i] < 0.0000000000000000000001 { // 没有设置过值的0 改成-1
211+
res[i] = -1.0
212+
}
213+
}
214+
return
215+
}
216+
217+
// @lc code=end

go/bfs-dfs/399/399_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package jzoffer
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
)
7+
8+
func Test399(t *testing.T) {
9+
fmt.Println(calcEquation(
10+
// [["a","b"],["c","b"],["d","b"],["w","x"],["y","x"],["z","x"],["w","d"]]
11+
[][]string{
12+
{"a", "b"}, {"c", "b"}, {"d", "b"}, {"w", "x"}, {"y", "x"}, {"z", "x"}, {"w", "d"}},
13+
[]float64{2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0},
14+
// [["a","c"],["b","c"],["a","e"],["a","a"],["x","x"],["a","z"]]
15+
[][]string{{"a", "c"}, {"b", "c"}, {"a", "e"}, {"a", "a"}, {"x", "x"}, {"a", "z"}}))
16+
17+
/*
18+
* 输入:equations = [["a","b"],["b","c"]], values = [2.0,3.0], queries =
19+
* [["a","c"],["b","a"],["a","e"],["a","a"],["x","x"]]
20+
* 输出:[6.00000,0.50000,-1.00000,1.00000,-1.00000]
21+
* 解释:
22+
* 条件:a / b = 2.0, b / c = 3.0
23+
* 问题:a / c = ?, b / a = ?, a / e = ?, a / a = ?, x / x = ?
24+
* 结果:[6.0, 0.5, -1.0, 1.0, -1.0 ]
25+
* 注意:x 是未定义的 => -1.0
26+
*/
27+
fmt.Println(calcEquation(
28+
[][]string{{"a", "b"}, {"b", "c"}},
29+
[]float64{2.0, 3.0},
30+
[][]string{{"a", "c"}, {"b", "a"}, {"a", "e"}, {"a", "a"}, {"x", "x"}}))
31+
32+
}

0 commit comments

Comments
 (0)