Leetcode 399. Evaluate Division[medium]

题目:
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& values, vector < pair < string, string> > queries , where equations.size() == values.size(), and the values are positive. This represents the equations. Return vector.

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.


这个题还是挺有意思的。
将每个分数当做图中的一个节点,边权为乘数的权值。
基础节点共有2n个(输入条件为n个分数),即这n个分数和这n个分数的倒数。
图中所有的新增节点的产生只有两种途径:
1.基础节点(基础分数)*基础分数(边)得到一个新增节点(新增分数)
2.新增节点(新增分数)*基础分数(边)得到一个新增节点(新增分数)

也就是说,新增节点是不可以作为边的,因为即便你想让新增节点作为边,这个分数的值在dfs之前是不知道的,所以也没办法作为边。

这里写图片描述

class Solution {
    #define N 11111
    #define M 111111
public:
    map< pair<string, string>, int> mp;
    double ans[N];
    bool vis[N];
    int cnt;
    int ts;

    int head[N], nxt[M], to[M];
    double len[M];

    void add(int u, int v, double w) {
        to[ts] = v; len[ts] = w; nxt[ts] = head[u]; head[u] = ts++;
        //cout << u << "   " << v << "   " << w << endl;
    }

    vector<double> calcEquation(vector< pair<string, string> > equations, vector<double>& values, vector< pair<string, string> > queries) {
        memset(head, -1, sizeof head);
        memset(vis, 0, sizeof vis);
        mp.clear();
        cnt = 0;
        ts = 0;
        pair<string, string> pr;
        int n = equations.size();
        for (int i = 0; i < n; i++) 
            if (mp[equations[i]] == 0) {
                mp[equations[i]] = ++cnt;
                add(0, mp[equations[i]], values[i]);//multiply

                pr.first = equations[i].second;
                pr.second = equations[i].first;

                equations.push_back(pr);
                values.push_back(1.0 / values[i]);

                if (mp[pr] == 0) mp[pr] = ++cnt;
                add(0, mp[pr], 1.0 / values[i]);//divide
            }
        int m = equations.size();
        for (int i = 0; i < equations.size(); i++) {//注意这两层循环 
            for (int j = 0; j < m; j++) {
                if (i == j) continue;
                if (equations[i].first == equations[j].second) {//multiply
                    pr.first = equations[j].first;
                    pr.second = equations[i].second;
                    if (mp[pr] == 0) {
                        mp[pr] = ++cnt;
                        equations.push_back(pr);//新增 
                    }
                    add(mp[equations[i]], mp[pr], values[j]);
                }
                if (equations[i].second == equations[j].first) {//multiply
                    pr.first = equations[i].first;
                    pr.second = equations[j].second;
                    if (mp[pr] == 0) {
                        mp[pr] = ++cnt;
                        equations.push_back(pr);//新增 
                    }
                    add(mp[equations[i]], mp[pr], values[j]);
                }
            }
        } 

        ans[0] = 1.0;
        vis[0] = true;
        dfs(0);
        vector<double> rt;
        for (int i = 0; i < queries.size(); i++) {
            if (mp[queries[i]] == 0) rt.push_back(-1.0);
            else rt.push_back(ans[mp[queries[i]]]);
        }
        return rt;
    }

    void dfs(int x) {
        for (int i = head[x]; ~i; i = nxt[i]) {
            if (!vis[to[i]]) {
                ans[to[i]] = ans[x] * len[i];
                vis[to[i]] = true;
                dfs(to[i]);
            } 
        }
    }
};

这题在写测试代码的时候挺恶心的,把测试代码也放上来吧。

int main() {
    Solution s;
    vector< pair<string, string> > vequations;
    vequations.push_back(make_pair("x1", "x2"));
    vequations.push_back(make_pair("x2", "x3"));
    vequations.push_back(make_pair("x3", "x4"));
    vequations.push_back(make_pair("x4", "x5"));

    vector<double> values;
    values.push_back(3.0);
    values.push_back(4.0);
    values.push_back(5.0);
    values.push_back(6.0);

    vector< pair<string, string> > queries;
    queries.push_back(make_pair("x1", "x5"));
    queries.push_back(make_pair("x5", "x2"));
    queries.push_back(make_pair("x2", "x4"));
    queries.push_back(make_pair("x2", "x2"));
    queries.push_back(make_pair("x2", "x9"));

    vector<double> ans;
    ans = s.calcEquation(vequations, values, queries);
    for (int i = 0; i < ans.size(); i++) cout << ans[i] << endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值