整体的思路是:
- 根据
equations
建图,首先找节点,将每个字母映射成数字,映射关系如map
所示 - 然后根据
equations
找边,并赋值 - 使用
Floyd
算法算出每两个节点之间的距离 - 遍历
queries
得到每组字符之间的距离
class Solution {
public double[] calcEquation(List<List<String>> equations, double[] values, List<List<String>> queries) {
int nvars = 0;
HashMap<String, Integer> map = new HashMap<>();
int n = equations.size();
for (int i = 0; i < n; ++i) {
if (!map.containsKey((equations.get(i)).get(0))) {
map.put((equations.get(i)).get(0), nvars++);
}
if (!map.containsKey((equations.get(i)).get(1))) {
map.put((equations.get(i)).get(1), nvars++);
}
}
double[][] d = new double[nvars][nvars];
for (int i = 0; i < nvars; ++i) {
Arrays.fill(d[i], -1.0);
}
for (int i = 0; i < n; ++i) {
int va = map.get((equations.get(i)).get(0)), vb = map.get((equations.get(i)).get(1));
d[va][vb] = values[i];
d[vb][va] = 1.0 / values[i];
}
for (int k = 0; k < nvars; ++k) {
for (int i = 0; i < nvars; ++i) {
for (int j = 0; j < nvars; ++j) {
if (d[i][k] > 1e-6 && d[k][j] > 1e-6) { // 这里注意精度
d[i][j] = d[i][k] * d[k][j];
}
}
}
}
int q_size = queries.size();
double[] res = new double[q_size];
for (int i = 0; i < q_size; ++i) {
double result = -1.0;
if (map.containsKey((queries.get(i)).get(0)) && map.containsKey((queries.get(i)).get(1))) {
int a = map.get((queries.get(i)).get(0)), b = map.get((queries.get(i)).get(1));
if (d[a][b] > 0) result = d[a][b];
}
res[i] = result;
}
return res;
}
}
这里要注意精度问题,在官方提交中,如果d[i][j]>0
则无法通过28用例,如图所示。
因此根据题目的精度要求,两点之间最小距离为0.00001
时可以,但是更大就不行了,因此把精度控制在0.000001