Evaluate Division

  • 问题来源
  • 问题简介

    给出一系列式子 a / b = k(k为非零小数),要求算出指定的算式,如:
    给出 a / b = 2.0, b / c = 3.0;
    则求 a / c。
    结果: 6.0
    若求不出,则为 -1。


解题思路


若有 a / b, b / c
则可求 a / c = a / b * b / c
同理,对于 a / b
若有 a / d, d / b
则可求 a / b
以此类推,直到无法继续拓展。
这就有点像分治了。问题是在求a / c 时,我们如何确定这个b的值?
如果将 a / b 看成 a->b,那么,a / b, b / c就可以看成 a -> b -> c
则:
我们从a开始遍历,看是否存在一条路径使得a和c是连通的。

这里需要注意的是,若我们有 a / b的值,那么我们也就同时拥有 b / a 的值了。
也就是说这道题涉及到的是无向图的遍历了。


时间复杂度 空间复杂度
O(未知) O(未知)

Code

class Solution {
public:
    vector<double> calcEquation(vector<pair<string, string>> equations, vector<double>& values, vector<pair<string, string>> queries) {
        unordered_map<string, unordered_map<string, double>> next;
        unordered_set<string> all;
        pair<string, string> cur;
        double val;
        for (int i = 0, len = equations.size(); i < len; i++) {
            cur = equations[i];
            val = values[i];
            next[cur.first][cur.second] = val;
            next[cur.second][cur.first] = 1 / val;
            all.insert(cur.first);
            all.insert(cur.second);
        }
        vector<double> rs(queries.size(), -1.0);
        auto it = rs.begin();
        for (auto &i : queries) {
            auto a_c = all;
            if (next.find(i.first) == next.end() || next.find(i.second) == next.end()) {
                *it++ = -1;
            } else {
                *it++ = dfs(i.first, i.second, next, a_c);
            }
        }
        return rs;
    }

    double dfs(const string &cur, const string &goal,
               unordered_map<string, unordered_map<string, double>> &next,
              unordered_set<string> &all) {
        if (cur == goal) {
            return next.find(cur) != next.end() ? !!(next[cur].begin() -> second) : -1;
        }
        if (next[cur].find(goal) != next[cur].end()) {
            return next[cur][goal];
        }
        all.erase(cur);
        auto &next_set = next[cur];
        double nextVal = -1;
        for (auto &i : next_set) {
            if (all.find(i.first) == all.end()) {
                continue;
            }
            nextVal = dfs(i.first, goal, next, all);
            if (nextVal != -1) {
                return nextVal * i.second;
            }
        }
        return -1;
    }
};

运行结果

Evaluate Division