You are given a 2D array of strings equations and an array of real numbers values, where equations[i] = [Ai, Bi] and values[i] means that Ai / Bi = values[i].
Determine if there exists a contradiction in the equations. Return true if there is a contradiction, or false otherwise.
Note:
When checking if two numbers are equal, check that their absolute difference is less than 10-5.
The testcases are generated such that there are no cases targeting precision, i.e. using double is enough to solve the problem.
Example 1:
Input: equations = [["a","b"],["b","c"],["a","c"]], values = [3,0.5,1.5]
Output: false
Explanation:
The given equations are: a / b = 3, b / c = 0.5, a / c = 1.5
There are no contradictions in the equations. One possible assignment to satisfy all equations is:
a = 3, b = 1 and c = 2.
Example 2:
Input: equations = [["le","et"],["le","code"],["code","et"]], values = [2,5,0.5]
Output: true
Explanation:
The given equations are: le / et = 2, le / code = 5, code / et = 0.5
Based on the first two equations, we get code / et = 0.4.
Since the third equation is code / et = 0.5, we get a contradiction.
Constraints:
1 <= equations.length <= 100
equations[i].length == 2
1 <= Ai.length, Bi.length <= 5
Ai, Bi consist of lowercase English letters.
equations.length == values.length
0.0 < values[i] <= 10.0
values[i] has a maximum of 2 decimal places.
Solutions
Solution 1: Weighted Union-Find
Thinking
Each equation gives a ratio of two variables. Different paths between the same pair may disagree. There are at most a few hundred variables and \(100\) equations, so a union-find structure can keep the components.
Map names to integers and let \(w[x]\) be the ratio from \(x\) to its root. On union, update weights by multiplication. If two variables already share a root, compare \(v \cdot w[a]\) with \(w[b]\) within the allowed error. A mismatch is a contradiction.
First, we convert the strings into integers starting from \(0\). Then, we traverse all the equations, map the two strings in each equation to the corresponding integers \(a\) and \(b\). If these two integers are not in the same set, we merge them into the same set and record the weights of the two integers, which is the ratio of \(a\) to \(b\). If these two integers are in the same set, we check whether their weights satisfy the equation. If not, we return true.
The time complexity is \(O(n \times \log n)\) or \(O(n \times \alpha(n))\), and the space complexity is \(O(n)\). Here, \(n\) is the number of equations.