
解法
并查集的思想,将数组转化为图中的权重边,并进行缩短路径,每个都指向根节点
class Solution {
public double[] calcEquation(List<List<String>> equations, double[] values, List<List<String>> queries) {
int size = equations.size();
// indexMap保存字符串对应的下标映射,方便UnionFind里维护数组
Map<String, Integer> indexMap = new HashMap(size * 2);
UnionFind unionFind = new UnionFind(size * 2);
int index = 0;
for (int i = 0; i < size; i++) {
List<String> equation = equations.get(i);
String v1 = equation.get(0);
String v2 = equation.get(1);
if (!indexMap.containsKey(v1)) {
indexMap.put(v1, index++);
}
if (!indexMap.containsKey(v2)) {
indexMap.put(v2, index++);
}
unionFind.union(indexMap.get(v1), indexMap.get(v2), values[i]);
}
int queriesSize = queries.size();
double[] res = new double[queriesSize];
for (int i = 0; i < queriesSize; i++) {
List<String> query = queries.get(i);
String v1 = query.get(0);
String v2 = query.get(1);
// 获取映射
Integer id1 = indexMap.get(v1);
Integer id2 = indexMap.get(v2);
if (id1 == null || id2 == null) {
res[i] = -1.0d;
} else {
res[i] = unionFind.isConnected(id1, id2);
}
}
return res;
}
private class UnionFind {
// 父节点是哪个
private int[] parent;
// 以当前点为起始点,parent对应的值为终点,对应的权重边
private double[] weight;
public UnionFind(int n) {
this.parent = new int[n];
this.weight = new double[n];
for (int i = 0; i < n; i++) {
parent[i] = i;
weight[i] = 1.0d;
}
}
// 寻找x对应的根节点,并计算到根节点的权重值
public int find(int x) {
if (x != parent[x]) {
int origin = parent[x];
parent[x] = find(parent[x]);
weight[x] *= weight[origin];
}
return parent[x];
}
public void union(int x, int y, double value) {
int RootX = find(x);
int RootY = find(y);
if (RootX == RootY) {
return;
}
parent[RootX] = RootY;
weight[RootX] = value * weight[y] / weight[x];
}
public double isConnected(int x, int y) {
int RootX = find(x);
int RootY = find(y);
if (RootX == RootY) {
return weight[x] / weight[y];
} else {
return -1.0d;
}
}
}
}
网友评论