leetcode399. Evaluate Division

栏目: 编程工具 · 发布时间: 5年前

内容简介:已知一些字母之间的关系式,问是否能够计算出其它字母之间的倍数关系?如已知假如我们将除数和被除数看做是图的顶点,将除数和被除数之间的倍数关系试做二者之间边的权重。即

题目要求

Equations are given 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.

Example:
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 ].

The input is: vector<pair<string, string>> equations, vector<double>& values, vector<pair<string, string>> queries , where equations.size() == values.size(), and the values are positive. This represents the equations. Return vector<double>.

According to the example above:

equations = [ ["a", "b"], ["b", "c"] ],
values = [2.0, 3.0],
queries = [ ["a", "c"], ["b", "a"], ["a", "e"], ["a", "a"], ["x", "x"] ]. 
 

The input is always valid. You may assume that evaluating the queries will result in no division by zero and there is no contradiction.

已知一些字母之间的关系式,问是否能够计算出其它字母之间的倍数关系?

如已知 a/b=2.0 b/c=3.0 问是否能够计算出 a/c, b/a, a/e, a/a, x/x 的值。如果无法计算得出,则返回-1。这里 x/x 的值因为在条件中无法获知x是否等于零,因此也无法计算其真实结果,也需要返回-1。

思路和代码

假如我们将除数和被除数看做是图的顶点,将除数和被除数之间的倍数关系试做二者之间边的权重。即 a/b=2.0 代表点a指向点b的边的权重为2.0,而点b指向点a的边的全中为1/2.0=0.5。

因此我们可以将输入的表达式转化为一个加权有向图,而题目的问题则被转化为求两个点之间是否能够找到一条边,如果无法找到,则返回-1,否则返回路径上每条边的权重的乘积。

代码如下:

public double[] calcEquation(List<List<String>> equations, double[] values, List<List<String>> queries) {
        //图的链式表示法
        Map<String, List<String>> pairs = new HashMap<>();
        //图上每条边的权重
        Map<String, List<Double>> valuedPairs = new HashMap<>();
        for(int i = 0 ; i < equations.size() ; i++) {
            //获取第i个方程式
            List<String> equation = equations.get(i);
            String multiplied = equation.get(0);//被除数
            String multiplier = equation.get(1);//除数
            //如果被除数从来没有添加到图中,则将其作为顶点在图中初始化
            if(!pairs.containsKey(multiplied)) {
                pairs.put(multiplied, new ArrayList<>());
                valuedPairs.put(multiplied, new ArrayList<>());
            }
            //如果除数从来没有添加到图中,则将其作为顶点在图中初始化
            if(!pairs.containsKey(multiplier)) {
                pairs.put(multiplier, new ArrayList<>());
                valuedPairs.put(multiplier, new ArrayList<>());
            }
            //添加边和边的权重
            pairs.get(multiplied).add(multiplier);
            pairs.get(multiplier).add(multiplied);
            valuedPairs.get(multiplied).add(values[i]);
            valuedPairs.get(multiplier).add(1.0 / values[i]);
        }
        
        //结果集
        double[] result = new double[queries.size()];
        for(int i = 0 ; i<queries.size() ; i++) {
            //在图中,以被除数作为顶点,深度优先遍历图,直到找到值为除数的顶点
            result[i] = dfs(queries.get(i).get(0), queries.get(i).get(1), pairs, valuedPairs, new HashSet<>(), 1.0);
            result[i] = result[i]==0.0 ? -1.0 : result[i];
        }
        return result;
    }
    
    public double dfs(String multiplied, String multiplier, Map<String, List<String>> pairs, Map<String, List<Double>> valuedPairs, Set<String> visited, double curResult) {
        //如果图中不包含该被除数顶点,则无法获知该表达式的值
        if(!pairs.containsKey(multiplied)) return 0.0;
        //如果再次访问过该被除数,说明找到了一条环路,则该深度优先遍历结果失败,直接抛弃
        if(visited.contains(multiplied)) return 0.0;
        //如果被除数等于除数,则返回1.0
        if(multiplied.equals(multiplier)) return curResult;
        visited.add(multiplied);
        //获得当前被除数的所有邻接顶点
        List<String> multipliers = pairs.get(multiplied);
        //获得所有邻接边的权重
        List<Double> multiplierValues = valuedPairs.get(multiplied);
        double tmp = 0.0;
        for(int i = 0 ; i<multipliers.size() ; i++) {
            //以邻接点为新的顶点,继续深度优先遍历
            //此时调用方法中curResult的值代表的是该原邻接点除以邻接点的值
            //如 a/b=2, b/c=3, 则a=2b,因此当我们以b作为邻接点寻找c时,需要记录原被除数是现被除数的两倍
            tmp = dfs(multipliers.get(i), multiplier, pairs, valuedPairs, visited, curResult * multiplierValues.get(i));
            //找到非零路径,结束深度优先遍历
            if(tmp != 0.0){
                break;
            }
        }
        visited.remove(multiplied);
        return tmp;
    }

以上所述就是小编给大家介绍的《leetcode399. Evaluate Division》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Black Box Society

The Black Box Society

Frank Pasquale / Harvard University Press / 2015-1-5 / USD 35.00

Every day, corporations are connecting the dots about our personal behavior—silently scrutinizing clues left behind by our work habits and Internet use. The data compiled and portraits created are inc......一起来看看 《The Black Box Society》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具