[Leetcode-42] [Union Check Set] 399. Evaluation of Division

Title description

Given the equation A / B = k, where A and B are variables represented by strings, and k is a floating-point number. Solve the problem according to the known equation and return the calculation result. If the result does not exist, it returns -1.0.

The input is always valid. You can assume that there will be no divisor 0 in the division operation, and there will be no contradictory results.

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
Question: 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]

提示:
1 <= equations.length <= 20
equations[i].length == 2
1 <= equations[i][0].length, equations[i][1].length <= 5
values.length == equations.length
0.0 < values[i] <= 20.0
1 <= queries.length <= 20
queries[i].length == 2
1 <= queries[i][0].length, queries[i][1].length <= 5
equations[i][0], equations[i][1], queries[i][0], queries[i][1] 由小写英文字母与数字组成

Source: LeetCode
Link: https://leetcode-cn.com/problems/evaluate-division The
copyright is owned by LeetCode . For commercial reprints, please contact the official authorization. For non-commercial reprints, please indicate the source.

Problem solving ideas

  • Finding a common ancestor, such as finding a / b, is actually finding a / root divided by b / root. Here we use union search, but do not compress the path.
  • Because you want to record the result of the division, you also need a map to record the value of the division by root. The high end can also be called the weight.
  • First, the root of each number is initialized to itself, and the weight is 1.
  • According to the known conditions, combine the two numbers in equations. If the root node of equation[i][0] is different from the root node of equations[i][1], set equations[i][0] The root node is set as a child node of the root node of equations[i][0], and the weight is updated/well, the actual code is as follows
    parent.put(p1.getKey(), p2.getKey());
    weight.put(p1.getKey(), val * p2.getValue() / p1.getValue());
    
  • In the getPair function, the function of finding the root node of the input node and returning the weight is realized

Code

class Solution {
    
    
    HashMap<String, String> parent = new HashMap<>();
    HashMap<String, Double> weight = new HashMap<>();
    // Pair<String, Double> String是祖先节点,Double是权重
    public Pair<String, Double> getPair(String node){
    
    
        if(!parent.containsKey(node)){
    
    
            return new Pair<String, Double>("", -1.0);
        }
        double _weight = 1;
        while(parent.get(node) != node){
    
    
        	// a/c = a/b * b/c,所以一直是乘的关系。
            _weight *= weight.get(node);
            node = parent.get(node);
        }
        return new Pair<>(node, _weight);
    }
    private void combine(String a, String b, double val){
    
    
        Pair<String, Double> p1 = getPair(a);
        Pair<String, Double> p2 = getPair(b);
        if(p1.getKey() == "" || p2.getKey() == "" ) return;
        if(p1.getKey() == p2.getKey()) return;
        parent.put(p1.getKey(), p2.getKey());
        weight.put(p1.getKey(), val * p2.getValue() / p1.getValue());
    }
    public double[] calcEquation(List<List<String>> equations, double[] values, List<List<String>> queries) {
    
    
        double[] res = new double[queries.size()];
        int i = 0;
        for(List<String> item : equations){
    
    
            if(getPair(item.get(0)).getKey() == ""){
    
    
                parent.put(item.get(0), item.get(0));
                weight.put(item.get(0), 1.0);
            }
            if(getPair(item.get(1)).getKey() == ""){
    
    
                parent.put(item.get(1), item.get(1));
                weight.put(item.get(1), 1.0);
            }
            combine(item.get(0), item.get(1), values[i++]);
        }
        i = 0;
        for(List<String> item : queries){
    
    
            Pair<String, Double> p1 = getPair(item.get(0));
            Pair<String, Double> p2 = getPair(item.get(1));
            if(!parent.containsKey(p1.getKey()) || !parent.containsKey(p2.getKey()) || p1.getKey() != p2.getKey()){
    
    
                res[i++] = -1.0;
            } else {
    
    
            	// a/b = (a*d*e*f) / (b*d*e*f)
                res[i++] = p1.getValue() / p2.getValue();
            }
        }
        return res;
    }
}

Guess you like

Origin blog.csdn.net/u010659877/article/details/109071936