剑指 Offer II 111. 计算除法

133 阅读1分钟

剑指 Offer II 111. 计算除法

  • 将整个问题建模成一张图:给定图中的一些点(变量),以及某些边的权值(两个变量的比值),试对任意两点(两个变量)求出其路径长(两个变量的比值)。
  • 因此,我们首先需要遍历 equations 数组,找出其中所有不同的字符串,并通过哈希表将每个不同的字符串映射成整数。
  • 在构建完图之后,对于任何一个查询,就可以从起点出发,通过广度优先搜索的方式,不断更新起点与当前点之间的路径长度,直到搜索到终点为止。
var calcEquation = function (arr, values, queries) {
    var k = 0;
    var map = new Map();
    var n = arr.length;
    for (var i = 0; i < n; i++) {
        if (!map.has(arr[i][0])) {
            map.set(arr[i][0], k++);
        }
        if (!map.has(arr[i][1])) {
            map.set(arr[i][1], k++);
        }
    }
    // 对于每个点,存储其直接连接到的所有点及对应的权值
    var brr = new Array(k).fill(0);
    for (var i = 0; i < k; i++) {
        brr[i] = [];
    }
    for (var i = 0; i < n; i++) {
        var va = map.get(arr[i][0]), vb = map.get(arr[i][1]);
        brr[va].push([vb, values[i]]);
        brr[vb].push([va, 1.0 / values[i]]);
    }

    var crr = queries.length;
    var drr = [];
    for (var i = 0; i < crr; i++) {
        var query = queries[i];
        var res = -1.0;
        if (map.has(query[0]) && map.has(query[1])) {
            var ia = map.get(query[0]), ib = map.get(query[1]);
            if (ia === ib) {
                res = 1.0;
            } else {
                var points = [];
                points.push(ia);
                var ratios = new Array(k).fill(-1.0);
                ratios[ia] = 1.0;
                while (points.length && ratios[ib] < 0) {
                    var x = points.pop();
                    for (var [y, val] of brr[x]) {
                        if (ratios[y] < 0) {
                            ratios[y] = ratios[x] * val;
                            points.push(y);
                        }
                    }
                }
                res = ratios[ib];
            }
        }
        drr[i] = res;
    }
    return drr;
};

代码调试

var arr = [["a","b"],["b","c"]], values = [2.0,3.0], queries = [["a","c"],["b","a"],["a","e"],["a","a"],["x","x"]]
console.log(calcEquation(arr, values, queries));