Leetcode-399 除法求值

Floyed

学习题解
问题本质为想要根据a/b=2,b/c=3导出a/c=6
将values中的权重关系转化为图的边,即为邻接矩阵的对应值。
Floyed算法:通过使用每一个点为中转点,能够找到图上任意两点的最短路径。
本题使用Floyed算法,以每一个点为中转点(最外层循环),找到图上任意两点的倍数关系。

DBL_MAX,DBL_MIN对应的头文件#include

class Solution {
public:
    vector<double> calcEquation(vector<vector<string>>& equations, vector<double>& values, vector<vector<string>>& queries) {
        unordered_map<string,int> word;
        vector<vector<double>> graph(100,vector<double>(100,DBL_MAX));
        int index=0;
        for(int i=0;i<equations.size();i++)
        {
            if(word.find(equations[i][0])==word.end())
                word[equations[i][0]]=index++;
            if(word.find(equations[i][1])==word.end())
                word[equations[i][1]]=index++;
            graph[ word[equations[i][0]]][ word[equations[i][1]]]=values[i];
            graph[ word[equations[i][1]]][ word[equations[i][0]]]=1.0/values[i];
        }
        for(int i=0;i<index;i++)
                graph[i][i]=1;
        for(int i=0;i<index;i++)
            for(int j=0;j<index;j++)
                for(int k=0;k<index;k++)
        {
            if(graph[j][k]==DBL_MAX&&graph[j][i]!=DBL_MAX&&graph[i][k]!=DBL_MAX)
            {
                graph[j][k]=graph[j][i]*graph[i][k];
            }
        }
        vector<double> res;
        for(int i=0;i<queries.size();i++)
        {
            if(word.find(queries[i][0])==word.end()||word.find(queries[i][1])==word.end()||graph[word[queries[i][0]]][word[queries[i][1]]]==DBL_MAX)
            {
                res.push_back(-1);
                continue;
            }
            res.push_back(graph[word[queries[i][0]]][word[queries[i][1]]]);
        }
        return res;
    }
};

带权并查集

关于并查集的介绍,参考题解。

对于a/b=2,在father中的关系为>,key对应的value中存储着根,以及根/自己的倍数关系。
将任意两个数的关系,转化为两个数和根的关系比。
unionFind:查找根并进行路径压缩
>,>转化为>,>
un:合并两个并查集
对于a和b分别找到a和b的根root1,root2,将一个根连到另一个根上,>
root1/root2=val=(root1/a)*(a/b)/(root2/b)

class Solution {
public:
	//查找根并进行路径压缩
    int unionFind(int index){
        int tmp=index;
        double num=1.0;
        while(index != father[index].first){
           num*=father[index].second;
           index=father[index].first;        
        }
        father[tmp].first=index;
        father[tmp].second=num;
        return index;
    }
    //合并
    void un(int dad,int son,double val){
        int root1 = unionFind(dad);
        int root2 = unionFind(son);
        if(root1 != root2){
            father[root2].first = root1;
            father[root2].second = father[dad].second * val / father[son].second;
        }
    }
    unordered_map<int,pair<int,double>> father;
    vector<double> calcEquation(vector<vector<string>>& equations, vector<double>& values, vector<vector<string>>& queries) {
        unordered_map<string,int> word;
        int index=0,dad,son;
        for(int i=0;i<equations.size();i++)
        {
            if(word.find(equations[i][0])==word.end())
            {
                word[equations[i][0]]=index++; 
                father[word[equations[i][0]]].first=word[equations[i][0]];
                father[word[equations[i][0]]].second=1;
            } 
            if(word.find(equations[i][1])==word.end())
            {
                word[equations[i][1]]=index++; 
                father[word[equations[i][1]]].first=word[equations[i][1]];
                father[word[equations[i][1]]].second=1;
            }
            un(word[equations[i][0]],word[equations[i][1]],values[i]);
        }
    vector<double> res;
    for(int i=0;i<queries.size();i++)
    {
        if(word.find(queries[i][0])==word.end()||word.find(queries[i][1])==word.end())
        {
            res.push_back(-1);
            continue;
        }
        dad=word[queries[i][0]];
        son=word[queries[i][1]];
        if(unionFind(dad)!=unionFind(son))
            res.push_back(-1);          
        else
        {
           res.push_back(father[son].second/father[dad].second); 
        }   
    }
    return res;
    }
};

你可能感兴趣的:(Leetcode)