Leetcode 399 Evaluate Division
- 题目
- 思路
- 代码
题目
You are given equations in the format A / B = k, where A and B are variables represented as strings, and k is a real number (floating-point number). Given some queries, return the answers. If the answer does not exist, return -1.0.
The input is always valid. You may assume that evaluating the queries will result in no division by zero and there is no contradiction.
Example 1:
Input: equations = [[“a”,“b”],[“b”,“c”]], values = [2.0,3.0], queries = [[“a”,“c”],[“b”,“a”],[“a”,“e”],[“a”,“a”],[“x”,“x”]]
Output: [6.00000,0.50000,-1.00000,1.00000,-1.00000]
Explanation:
Given: a / b = 2.0, b / c = 3.0
queries are: a / c = ?, b / a = ?, a / e = ?, a / a = ?, x / x = ?
return: [6.0, 0.5, -1.0, 1.0, -1.0 ]
Example 2:
Input: equations = [[“a”,“b”],[“b”,“c”],[“bc”,“cd”]], values = [1.5,2.5,5.0], queries = [[“a”,“c”],[“c”,“b”],[“bc”,“cd”],[“cd”,“bc”]]
Output: [3.75000,0.40000,5.00000,0.20000]
Example 3:
Input: equations = [[“a”,“b”]], values = [0.5], queries = [[“a”,“b”],[“b”,“a”],[“a”,“c”],[“x”,“y”]]
Output: [0.50000,2.00000,-1.00000,-1.00000]
Constraints:
1 <= equations.length <= 20
equations[i].length == 2
1 <= equations[i][0], equations[i][1] <= 5
values.length == equations.length
0.0 < values[i] <= 20.0
1 <= queries.length <= 20
queries[i].length == 2
1 <= queries[i][0], queries[i][1] <= 5
equations[i][0], equations[i][1], queries[i][0], queries[i][1] consist of lower case English letters and digits.
思路
最开始想的随便记一个数为1,根据倍数关系把别的数都算出来,操作以后发现有一个问题,例如先有a/b=2a/b = 2a/b=2,此时记录a=2,b=1a = 2,b = 1a=2,b=1,再有c/d=2c/d = 2c/d=2,记录c=2,d=1c = 2,d = 1c=2,d=1,这时如果再有a/c=2a/c = 2a/c=2等类似的式子结果就会不正确。
换一个思路考虑,一个字符串为一个节点,可以构造出一个有向图,a/b=ka/b = ka/b=k对应于两条边(a,b,k)(a,b,k)(a,b,k)和(b,a,1/k)(b,a,1/k)(b,a,1/k)(e=(startvertex,endvertex,weight)e=(start vertex, end vertex, weight)e=(startvertex,endvertex,weight))。然后发现如果求a/ca/ca/c就是a/ba/ba/b和b/cb/cb/c两条边weight的乘积。
所以最后先构造一个图,在以query中的两个字符串为起始点进行dfs,根据题目要求,起始点间的路径如果存在一定唯一。
代码
class Solution {
public double[] calcEquation(List<List<String>> equations, double[] values, List<List<String>> queries) {
HashMap<String, HashMap<String, Double>> map = new HashMap<>();List<String> eq;for (int i = 0; i < values.length; i++) {
eq = equations.get(i);if (!map.containsKey(eq.get(0))) {
map.put(eq.get(0), new HashMap<>());}if (!map.containsKey(eq.get(1))) {
map.put(eq.get(1), new HashMap<>());}map.get(eq.get(0)).put(eq.get(1), values[i]);map.get(eq.get(1)).put(eq.get(0), 1 / values[i]); // (a, b) -> 2, (b, a) -> 0.5}double[] res = new double[queries.size()];for (int i = 0; i < queries.size(); i++) {
res[i] = dfs(1, queries.get(i).get(0), queries.get(i).get(1), map, new HashSet<>());}return res;}public double dfs(double res, String curr, String end, HashMap<String, HashMap<String, Double>> map, HashSet<String> visited) {
if (!map.containsKey(curr) || !map.containsKey(end)) return -1;double finalRes = -1;if (visited.contains(curr)) return -1; // already visitedif (curr.equals(end)) return res;visited.add(curr);for (String s : map.get(curr).keySet()) {
// loop through neighborsif ((finalRes = dfs(res * map.get(curr).get(s), s, end, map, visited)) != -1) break;}visited.remove(curr);return finalRes;}
}