
class Solution { public double[] calcEquation(List<List<String>> equations, double[] values, List<List<String>> queries) { int equationsSize = equations.size(); UnionFind unionFind = new UnionFind(2 * equationsSize); //最大需要两倍空间(每个list有两个字母) //第一步,预处理,将变量的值与id进行映射,使得并查集的底层用数组实现,方便编码 Map<String, Integer> map = new HashMap<>(2 * equationsSize);//初始化map将字母关系转化为数字 int id = 0; //对应values中索引和映射字母 for (int i = 0; i < equationsSize; i++) { List<String> equation = equations.get(i); String var1 = equation.get(0); String var2 = equation.get(1); if (!map.containsKey(var1)) { map.put(var1, id++); } if (!map.containsKey(var2)) { map.put(var2, id++); } //并查询查询之前执行一次合并操作 unionFind.union(map.get(var1), map.get(var2), values[i]); } //第二步 做查询 int queriesSize = queries.size(); double[] res = new double[queriesSize]; for (int i = 0; i < queriesSize; i++) { String var1 = queries.get(i).get(0); String var2 = queries.get(i).get(1); //得到需要查询的字母对应的id Integer id1 = map.get(var1); Integer id2 = map.get(var2); if (id1 == null || id2 == null) { res[i] = -1.0; } else { //两个节点都存在,则转化为和父节点的关系进行比较 res[i] = unionFind.isConnected(id1, id2); } } return res; } class UnionFind { private int[] parent; //表示每个节点对应的父节点的id 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; } } /** * 合并操作 * * @param x,y 两个节点 * @param value 有向边的权值 */ 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] = weight[y] * value / weight[x]; } /** * 路径压缩 * * @param id 输入节点的id * @return 根节点的id */ private int find(int id) { if (id != parent[id]) { //根据上一次节点的权值来更新当前节点的权值 int preNode = parent[id]; parent[id] = find(parent[id]); weight[id] *= weight[preNode]; } return parent[id]; } 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; } } }}
hot100-除法求值