Leetcode 399: 除法求值

Leetcode 399: 除法求值

题目

给你一个变量对数组 equations 和一个实数值数组 values 作为已知条件,其中 equations[i] = [Ai, Bi] 和 values[i] 共同表示等式 Ai / Bi = values[i] 。每个 Ai 或 Bi 是一个表示单个变量的字符串。

另有一些以数组 queries 表示的问题,其中 queries[j] = [Cj, Dj] 表示第 j 个问题,请你根据已知条件找出 Cj / Dj = ? 的结果作为答案。

返回 所有问题的答案 。如果存在某个无法确定的答案,则用 -1.0 替代这个答案。如果问题中出现了给定的已知条件中没有出现的字符串,也需要用 -1.0 替代这个答案。

注意:输入总是有效的。你可以假设除法运算中不会出现除数为 0 的情况,且不存在任何矛盾的结果。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/evaluate-division

解题思路

这道题可以转换成:求图中任意两个节点之间的距离问题.

具体来看,对于等式Ai / Bi = values[i]而言,我们可以把变量Ai 和 Bi看成图中的两个节点,而这两个节点之间的距离就是values[i]. 那假设还存在等式 Bi / Ci = values[j], 那么Ai / Ci 的结果就是: Ai / Bi ∗ * Bi / Ci = values[i] ∗ * values[j] (也就是Ai和Ci之间的距离).

由于题目中说明每个方程是没有矛盾的,也就是两个变量相除的结果只有一个,因此两个变量(节点)间的最短距离就是他们之间的距离(因为有且只有一条路径). 所以,就可以用Floyd算法在 O ( n 3 ) O(n^3) O(n3)来求得任意两个节点之间的距离。每次查询,只需要 O ( 1 ) O(1) O(1)的时间复杂度。

Leetcode代码

class Solution {
public:
    vector calcEquation(vector>& equations, vector& values, vector>& queries) {
        unordered_map> g; //用来存储 图
        unordered_set hash; //记录出现过的变量名
        int n = values.size();
        for (int i = 0; i < n; i ++ ) {
            string a = equations[i][0], b = equations[i][1];
            double c = values[i];
            g[a][b] = c, g[b][a] = 1.0 / c; //题目中指明values是大于0的
            hash.insert(a), hash.insert(b);
        }

        for (auto k: hash)   //floyd算法
            for (auto i: hash)
                for (auto j: hash)
                    if (g[i][k] != 0 && g[k][j] != 0)
                        g[i][j] = g[i][k] * g[k][j];
        vector res;
        for (auto query: queries) {
            string a = query[0], b = query[1];
            if (g[a][b]) // g[a][b] == 0 表示 a 与 b 之间没有通路
                res.push_back(g[a][b]);
            else res.push_back(-1);
        }
        return res;
    }
};

你可能感兴趣的:(leetcode,算法,leetcode)