LeetCode 399. 除法求值

LeetCode 399. 除法求值_第1张图片
来自LeetCode题解

方法一:并查集

思路:构建带权值边的并查集,对于每个方程式有两种情况:

  1. 查询是否联通,若不联通,则答案为-1.0
  2. 若联通,则求出其与根相除的结果,根据结果计算方程式

对于题目示例:

  1. 构造并查集:a->b->c,其中a->b的边的权值为2.0,b->c的边的权值为3.0
  2. 以计算b/a时为例,以root结点为桥梁,计算b/a的值:
    (1).首先计算b/root,这里root为c,则b/c = 3.0
    (2). 然后计算a/root,这里root为c,则a/c = a/b * b/c = 2.0 * 3.0 = 6.0
    (3). 最后计算方程式结果:b/a = (b/root)/(a/root) = 3.0/6.0 = 0.5
    注意:

根据以上分析可知,该并查集不能进行路径压缩和rank优化等操作,并查集本身结构必须与方程式结构相同,否则计算出来的结果必定出错。

其实结构也可以不相同,但是结构变化时,边的指向也就改变了,必须注意更新边的权重。

class Solution {
private:
    unordered_map<string, string>fa;//存当前结点的父母
    unordered_map<string, double>weights;//存当前结点值/父母值的结果
public:
    pair<string, double>find(string s) {
        if (fa.find(s) == fa.end()) return { "",-1.0 };//fa中没有a
        double res = -1.0;
        while (s != fa[s]) {
            res *= weights[s];
            s = fa[s];// 路径压缩后还需更新weights,这里就不路径压缩了
        }
        return { s,res };
    }
    void connect(string a, string b, double a_b) {
        pair<string, double>p1 = find(a), p2 = find(b);
        if (p1.first == "" || p2.first == "") return;
        if (p1.first == p2.first) return;
        fa[p1.first] = p2.first;
        weights[p1.first] = 1 / p1.second * a_b * p2.second;
    }
    vector<double> calcEquation(vector<vector<string>>& equations, vector<double>& values, vector<vector<string>>& queries) {
        for (int i = 0; i < equations.size(); ++i) {
            string a = equations[i][0], b = equations[i][1];
            if (fa.find(a) == fa.end()) {
                fa[a] = a; weights[a] = 1.0;
            }
            if (fa.find(b) == fa.end()) {
                fa[b] = b; weights[b] = 1.0;
            }
            connect(a, b, values[i]);
        }
        vector<double>ans;
        for (auto& q : queries) {
            string a = q[0], b = q[1];
            pair<string, double>p1 = find(a), p2 = find(b);
            if (p1.first != p2.first || p1.first == "" || p2.first == "")
                ans.push_back(-1.0);
            else ans.push_back(p1.second / p2.second);
        }
        return ans;
    }
};

你可能感兴趣的:(#,LeetCode)