LeetCode 399 Evaluate Division(BFS)

Equations are given in the format A / B = k, where A and B are variables represented as strings, and k is a real number (floating point number). Given some queries, return the answers. If the answer does not exist, return -1.0.

Example:
Given a / b = 2.0, b / c = 3.0. 
queries are: a / c = ?, b / a = ?, a / e = ?, a / a = ?, x / x = ? . 
return [6.0, 0.5, -1.0, 1.0, -1.0 ].

The input is: vector<pair<string, string>> equations, vector<double>& values, vector<pair<string, string>> queries , where equations.size() == values.size(), and the values are positive. This represents the equations. Return vector<double>.

According to the example above:

equations = [ ["a", "b"], ["b", "c"] ],
values = [2.0, 3.0],
queries = [ ["a", "c"], ["b", "a"], ["a", "e"], ["a", "a"], ["x", "x"] ]. 

The input is always valid. You may assume that evaluating the queries will result in no division by zero and there is no contradiction.

题目大意:给出一些形如A / B = k的等式,其中A和B都是字符串,k是浮点数。然后给出一些未知的查询,返回查询结果;如果结果不存在,返回-1。

例如:

给出a / b = 2.0, b / c = 3.0.

查询有a / c = ?, b / a = ?, a / e = ?, a / a = ?, x / x = ?.

返回结果是[6.0, 0.5, -1.0, 1.0, -1.0].

解题思路:

对于A / B = k,把A和B看成图上的节点,k则是由节点A指向节点B的一条有向边上的权值;1/k则是由B指向A的一条有向边上的权值。按照这个关系建图,然后根据查询遍历图中的节点,DFS、BFS和双向BFS都可以。注意因为A和B都是字符串,所以要把他们映射成整型数再建图。

代码如下:

const int maxn = 1000;
struct Edge {
    int from, to;
    double cost;
    Edge(int u, int v, double d):from(u), to(v), cost(d){}
};

class Solution {
public:
    void addEdge(int from, int to, double cost) {
        edges.push_back(Edge(from, to, cost));
        G[from].push_back(edges.size()-1);
    }
    
    double bfs(int from, int to) {
        queue<pair<int, double>> que;
        que.push(make_pair(from, 1));
        vis[from] = true;
        while(que.size()){
            pair<int, double> p = que.front();
            que.pop();
            if(p.first == to) return p.second;
            for(int i = 0;i < G[p.first].size();i++){
                Edge e = edges[G[p.first][i]];
                if(vis[e.to]) continue;
                que.push(make_pair(e.to, p.second * e.cost));
                vis[e.to] = true;
            }
        }
        return -1;
    }
    
    vector<double> calcEquation(vector<pair<string, string>> equations, vector<double>& values,
                                vector<pair<string, string>> queries) {
        for(int i = 0, j = 1;i < equations.size();i++) {
            pair<string, string> p = equations[i];
            
            if(!id[p.first])id[p.first] = j++;
            if(!id[p.second])id[p.second] = j++;
            
            addEdge(id[p.first], id[p.second], values[i]);
            addEdge(id[p.second], id[p.first], 1.0/values[i]);
        }
        
        vector<double> ans;
        for(int i = 0; i < queries.size();i++) {
            pair<string, string> p = queries[i];
            if(id[p.first] && id[p.second]){
                memset(vis, 0, sizeof(vis));
                double d = bfs(id[p.first], id[p.second]);
                ans.push_back(d);
            }else {
                ans.push_back(-1);
            }
        }
        return ans;
    }
private:
    unordered_map<string, int> id;
    vector<Edge> edges;
    vector<int> G[maxn];
    bool vis[maxn];
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值