399. 除法求值(并查集)
399. 除法求值
给你一个变量对数组 equations 和一个实数值数组 values 作为已知条件,其中 equations[i] = [Ai, Bi] 和 values[i] 共同表示等式 Ai / Bi = values[i] 。每个 Ai 或 Bi 是一个表示单个变量的字符串。
另有一些以数组 queries 表示的问题,其中 queries[j] = [Cj, Dj] 表示第 j 个问题,请你根据已知条件找出 Cj / Dj = ? 的结果作为答案。
返回 所有问题的答案 。如果存在某个无法确定的答案,则用 -1.0 替代这个答案。如果问题中出现了给定的已知条件中没有出现的字符串,也需要用 -1.0 替代这个答案。
注意:输入总是有效的。你可以假设除法运算中不会出现除数为 0 的情况,且不存在任何矛盾的结果。
示例 1:
输入:equations = [["a","b"],["b","c"]], values = [2.0,3.0], queries = [["a","c"],["b","a"],["a","e"],["a","a"],["x","x"]] 输出:[6.00000,0.50000,-1.00000,1.00000,-1.00000] 解释: 条件: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 ]
示例 2:
输入:equations = [["a","b"],["b","c"],["bc","cd"]], values = [1.5,2.5,5.0], queries = [["a","c"],["c","b"],["bc","cd"],["cd","bc"]] 输出:[3.75000,0.40000,5.00000,0.20000]
示例 3:
输入:equations = [["a","b"]], values = [0.5], queries = [["a","b"],["b","a"],["a","c"],["x","y"]] 输出:[0.50000,2.00000,-1.00000,-1.00000]
提示:
1 <= equations.length <= 20equations[i].length == 21 <= Ai.length, Bi.length <= 5values.length == equations.length0.0 < values[i] <= 20.01 <= queries.length <= 20queries[i].length == 21 <= Cj.length, Dj.length <= 5Ai, Bi, Cj, Dj由小写英文字母与数字组成
1 #include <iostream> 2 #include <vector> 3 #include <algorithm> 4 #include <string> 5 #include <unordered_map> 6 7 using namespace std; 8 9 class Solution { 10 public: 11 vector<int> parent; // 存储当前节点的根节点 12 vector<double> weight; // 存储当前节点到根节点的权值 13 void initUnionFind(int n) { 14 parent.resize(n); 15 weight.resize(n); 16 for (int i = 0; i < n; i++) { 17 parent[i] = i; // 初始每个集合只包含自己 18 weight[i] = 1; // 自己与自己的商为1 19 } 20 } 21 // 获取x与y的商 22 double getTheQuotientOfTwoNumbers(int x, int y) { 23 int xRoot = findRoot(x); 24 int yRoot = findRoot(y); 25 // 如果x与y在同一集合中,则获取x与y的商,否则不能获取到商 26 if (xRoot == yRoot){ 27 return (weight[x] / weight[y]); 28 } else { 29 return -1.0; 30 } 31 } 32 void unify(int x, int y, double value) { 33 int xRoot = findRoot(x); 34 int yRoot = findRoot(y); 35 if (xRoot == yRoot) { 36 return; 37 } 38 parent[xRoot] = yRoot; 39 weight[xRoot] = (weight[y] * value) / weight[x]; // 合并两集合时,更新节点权值 40 return; 41 } 42 int findRoot(int x) { 43 if (x != parent[x]) { 44 int next = parent[x]; 45 parent[x] = findRoot(parent[x]); 46 weight[x] *= weight[next]; 47 } 48 return parent[x]; 49 } 50 vector<double> calcEquation(vector<vector<string>>& equations, vector<double>& values, vector<vector<string>>& queries) { 51 int n = equations.size(); 52 initUnionFind(2 * n); 53 unordered_map<string, int> hashMap; // 存储字符串与数字的映射关系 54 hashMap.reserve(2 * n); 55 int id = 0; 56 for (int i = 0; i < n; i++) { 57 string str1 = equations[i][0]; 58 string str2 = equations[i][1]; 59 if (hashMap.count(str1) == 0) { 60 hashMap[str1] = id; 61 id++; 62 } 63 if (hashMap.count(str2) == 0) { 64 hashMap[str2] = id; 65 id++; 66 } 67 unify(hashMap[str1], hashMap[str2], values[i]); 68 } 69 cout << "hashMap:" << endl; 70 for (auto &val : hashMap) { 71 cout << "key:" << val.first << ", value:" << val.second << endl; 72 } 73 cout << "parent:" << endl; 74 for (auto &val : parent) { 75 cout << val << " "; 76 } 77 cout << endl; 78 cout << "weight:" << endl; 79 for (int i = 0; i < 2 * n; i++) { 80 cout << "weight[" << i << "] = " << weight[i] << endl; 81 } 82 // 查询操作 83 vector<double> ans; 84 for (unsigned int i = 0; i < queries.size(); i++) { 85 string str1 = queries[i][0]; 86 string str2 = queries[i][1]; 87 if (hashMap.count(str1) > 0 && hashMap.count(str2) > 0) { 88 ans.push_back(getTheQuotientOfTwoNumbers(hashMap[str1], hashMap[str2])); 89 } else { 90 ans.push_back(-1.0); 91 } 92 } 93 cout << "ans:" << endl; 94 for (auto &val : ans) { 95 cout << val << " "; 96 } 97 cout << endl; 98 return ans; 99 } 100 }; 101 102 int main() 103 { 104 /* 105 * [["x1","x2"],["x2","x3"],["x3","x4"],["x4","x5"]] 106 * [3.0,4.0,5.0,6.0] 107 * [["x1","x5"],["x5","x2"],["x2","x4"],["x2","x2"],["x2","x9"],["x9","x9"]] 108 */ 109 Solution *test = new Solution(); 110 vector<vector<string>> equations = { 111 {"x1", "x2"}, {"x2", "x3"}, {"x3", "x4"}, {"x4", "x5"} 112 }; 113 vector<double> values = {3.0, 4.0, 5.0, 6.0}; 114 vector<vector<string>> queries = { 115 {"x1", "x5"}, {"x5", "x2"}, {"x2", "x4"}, {"x2", "x2"}, {"x2", "x9"}, {"x9", "x9"} 116 }; 117 vector<double> ans = test->calcEquation(equations, values, queries); 118 119 std::cout << endl; 120 return 0; 121 }
浙公网安备 33010602011771号