|
| 1 | +[](https://github.com/LeetCode-in-TypeScript/LeetCode-in-TypeScript) |
| 2 | +[](https://github.com/LeetCode-in-TypeScript/LeetCode-in-TypeScript/fork) |
| 3 | + |
| 4 | +## 399\. Evaluate Division |
| 5 | + |
| 6 | +Medium |
| 7 | + |
| 8 | +You are given an array of variable pairs `equations` and an array of real numbers `values`, where <code>equations[i] = [A<sub>i</sub>, B<sub>i</sub>]</code> and `values[i]` represent the equation <code>A<sub>i</sub> / B<sub>i</sub> = values[i]</code>. Each <code>A<sub>i</sub></code> or <code>B<sub>i</sub></code> is a string that represents a single variable. |
| 9 | + |
| 10 | +You are also given some `queries`, where <code>queries[j] = [C<sub>j</sub>, D<sub>j</sub>]</code> represents the <code>j<sup>th</sup></code> query where you must find the answer for <code>C<sub>j</sub> / D<sub>j</sub> = ?</code>. |
| 11 | + |
| 12 | +Return _the answers to all queries_. If a single answer cannot be determined, return `-1.0`. |
| 13 | + |
| 14 | +**Note:** The input is always valid. You may assume that evaluating the queries will not result in division by zero and that there is no contradiction. |
| 15 | + |
| 16 | +**Example 1:** |
| 17 | + |
| 18 | +**Input:** equations = \[\["a","b"],["b","c"]], values = [2.0,3.0], queries = \[\["a","c"],["b","a"],["a","e"],["a","a"],["x","x"]] |
| 19 | + |
| 20 | +**Output:** [6.00000,0.50000,-1.00000,1.00000,-1.00000] |
| 21 | + |
| 22 | +**Explanation:** |
| 23 | + |
| 24 | +Given: _a / b = 2.0_, _b / c = 3.0_ |
| 25 | + |
| 26 | +queries are: _a / c = ?_, _b / a = ?_, _a / e = ?_, _a / a = ?_, _x / x = ?_ |
| 27 | + |
| 28 | +return: [6.0, 0.5, -1.0, 1.0, -1.0 ] |
| 29 | + |
| 30 | +**Example 2:** |
| 31 | + |
| 32 | +**Input:** equations = \[\["a","b"],["b","c"],["bc","cd"]], values = [1.5,2.5,5.0], queries = \[\["a","c"],["c","b"],["bc","cd"],["cd","bc"]] |
| 33 | + |
| 34 | +**Output:** [3.75000,0.40000,5.00000,0.20000] |
| 35 | + |
| 36 | +**Example 3:** |
| 37 | + |
| 38 | +**Input:** equations = \[\["a","b"]], values = [0.5], queries = \[\["a","b"],["b","a"],["a","c"],["x","y"]] |
| 39 | + |
| 40 | +**Output:** [0.50000,2.00000,-1.00000,-1.00000] |
| 41 | + |
| 42 | +**Constraints:** |
| 43 | + |
| 44 | +* `1 <= equations.length <= 20` |
| 45 | +* `equations[i].length == 2` |
| 46 | +* <code>1 <= A<sub>i</sub>.length, B<sub>i</sub>.length <= 5</code> |
| 47 | +* `values.length == equations.length` |
| 48 | +* `0.0 < values[i] <= 20.0` |
| 49 | +* `1 <= queries.length <= 20` |
| 50 | +* `queries[i].length == 2` |
| 51 | +* <code>1 <= C<sub>j</sub>.length, D<sub>j</sub>.length <= 5</code> |
| 52 | +* <code>A<sub>i</sub>, B<sub>i</sub>, C<sub>j</sub>, D<sub>j</sub></code> consist of lower case English letters and digits. |
| 53 | + |
| 54 | +## Solution |
| 55 | + |
| 56 | +```typescript |
| 57 | +type MapType = Map<string, string> |
| 58 | +type RateType = Map<string, number> |
| 59 | + |
| 60 | +function calcEquation(equations: [string, string][], values: number[], queries: [string, string][]): number[] { |
| 61 | + const root: MapType = new Map() |
| 62 | + const rate: RateType = new Map() |
| 63 | + for (const [x, y] of equations) { |
| 64 | + if (!root.has(x)) { |
| 65 | + root.set(x, x) |
| 66 | + rate.set(x, 1.0) |
| 67 | + } |
| 68 | + if (!root.has(y)) { |
| 69 | + root.set(y, y) |
| 70 | + rate.set(y, 1.0) |
| 71 | + } |
| 72 | + } |
| 73 | + for (let i = 0; i < equations.length; ++i) { |
| 74 | + const [x, y] = equations[i] |
| 75 | + union(x, y, values[i], root, rate) |
| 76 | + } |
| 77 | + const result: number[] = [] |
| 78 | + for (const [x, y] of queries) { |
| 79 | + if (!root.has(x) || !root.has(y)) { |
| 80 | + result.push(-1.0) |
| 81 | + } else { |
| 82 | + const rootX = findRoot(x, x, 1.0, root, rate) |
| 83 | + const rootY = findRoot(y, y, 1.0, root, rate) |
| 84 | + if (rootX === rootY) { |
| 85 | + result.push(rate.get(x)! / rate.get(y)!) |
| 86 | + } else { |
| 87 | + result.push(-1.0) |
| 88 | + } |
| 89 | + } |
| 90 | + } |
| 91 | + return result |
| 92 | +} |
| 93 | + |
| 94 | +function union(x: string, y: string, value: number, root: MapType, rate: RateType): void { |
| 95 | + const rootX = findRoot(x, x, 1.0, root, rate) |
| 96 | + const rootY = findRoot(y, y, 1.0, root, rate) |
| 97 | + |
| 98 | + if (rootX !== rootY) { |
| 99 | + root.set(rootX, rootY) |
| 100 | + const rateX = rate.get(x)! |
| 101 | + const rateY = rate.get(y)! |
| 102 | + rate.set(rootX, (value * rateY) / rateX) |
| 103 | + } |
| 104 | +} |
| 105 | + |
| 106 | +function findRoot(originalX: string, x: string, rateSoFar: number, root: MapType, rate: RateType): string { |
| 107 | + if (root.get(x) === x) { |
| 108 | + root.set(originalX, x) |
| 109 | + rate.set(originalX, rateSoFar * rate.get(x)!) |
| 110 | + return x |
| 111 | + } |
| 112 | + return findRoot(originalX, root.get(x)!, rateSoFar * rate.get(x)!, root, rate) |
| 113 | +} |
| 114 | + |
| 115 | +export { calcEquation } |
| 116 | +``` |
0 commit comments