带权并查集:Leetcode 399 除法求值

梦想不抛弃苦心追求的人,只要不停止追求,你们会沐浴在梦想的光辉之中。再美好的梦想与目标,再完美的计划和方案,如果不能尽快在行动中落实,最终只能是纸上谈兵,空想一番。只要瞄准了大方向,坚持不懈地做下去,才能够扫除挡在梦想前面的障碍,实现美好的人生蓝图。带权并查集:Leetcode 399 除法求值,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

带权并查集:Leetcode 399 除法求值

问题:

在这里插入图片描述

思路:

构建带权值边的并查集,对于每个方程式有两种情况:
查询是否联通,若不联通,则答案为-1.0
若联通,则求出其与根相除的结果,根据结果计算方程式。

例如,对于题目示例:

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

建立map<string,string>保存节点的parent,建立map<string,double> 保存节点除以parent的值
以a/b=2.0 ,b/c=3.0为例:
在这里插入图片描述
find函数用于返回节点的根以及节点除以根的值

union函数在合并的同时需对weight进行更新:

parent[rootA.first]=rootB.first;
weight[rootA.first]=1/rootA.second*a_div_b*rootB.second;

rootA.second由find(a)的返回值得到,即等于a/a的根
a_div_b等于a/b
rootB.second由find(b)的返回值得到,即等于b/b的根
weight[rootA.first]的值应等于 a的根/b的根
即weight[rootA.first]=1/rootA.second * a_div_b * rootB.second
在这里插入图片描述
对每个已知方程式的两个字符串进行union操作

对每个未知方程式的两个字符串进行find操作
若两个字符串的根均存在且相同,则返回两个find函数的商,即(a/root)/(b/root) = a/b即为所求

代码:

class Solution {
public:
    unordered_map< string,string > parent;
    unordered_map< string,double > weight;
    pair< string,double > find( string a )
    {
        if( parent.find( a )==parent.end() )
            return { " ",-1.0 };
        double result=1.0;
        while( parent[a]!=a )
        {
            result*=weight[a];
            a=parent[a];
        }
        return {a,result};      
    }
    void set_union( string a,string b,double a_div_b )
    {
        pair< string,double > rootA=find(a);
        pair< string,double > rootB=find(b);
        if( rootA.first==" " || rootB.first==" " )
            return;
        if( rootA.first==rootB.first )
            return;
        parent[rootA.first]=rootB.first;
        weight[rootA.first]=1/rootA.second*a_div_b*rootB.second;
    }
    vector<double> calcEquation(vector<vector<string>>& equations, vector<double>& values, vector<vector<string>>& queries) {
        int i;
        for( i=0;i<equations.size();i++ )
        {
            string a=equations[i][0];
            string b=equations[i][1];
            if( parent.find( a )==parent.end() )
            {
                parent[a]=a;
                weight[a]=1;
            }
            if( parent.find(b)==parent.end() )
            {
                parent[b]=b;
                weight[b]=1;
            }
            set_union( a,b,values[i] );
        }
        vector<double> ans;
        for( i=0;i<queries.size();i++ )
        {
            string a=queries[i][0];
            string b=queries[i][1];
            pair<string,double> a_div_root =find(a);
            pair<string,double> b_div_root = find(b);
            if( a_div_root.first==" " || b_div_root.first==" " || a_div_root.first!=b_div_root.first )
                ans.push_back(-1.0);
            else
                ans.push_back( a_div_root.second/b_div_root.second );
        }
        return ans;
    }
};

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/153837.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!