Leetcode evaluate Division

题目

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. Returnvector<double>.

题目分析

一开始,看到这道题的时候,想过用并查集的方法来确定是否可解,后来发现并查集行不通,通过dfs来看能否寻找到路径更合适。
并查集举例:

["a", "e"]["b", "e"]

这里建立并查集后,因为e的上源是a和b,所以没法通过寻找parent来确定是否有解。

解题步骤:
1. 首先,该题目的输入是string,和平时acm中简便的int不同,因此需要将string映射到int。这里建立了一个map<string, int> idx。但其实通过建立一个map包含map也可以直接处理,但可能不够熟练,所以就还是用一个映射来解决这个string的问题
2. 建立一个graph,我把这个division的两个参数看作结点,求出来的value作为边的权值,建立图。
3. 通过dfs搜索,看是否有路径,如果没有路径则返回0(因为输入都是正整数,不可能出现0),且继续搜索,若有路径则直接返回,因为计算出的数值具有唯一性。

源代码

class Solution {
public:
    vector<double> calcEquation(vector<pair<string, string>> equations, vector<double>& values, vector<pair<string, string>> queries) {
        //若可以计算,则通过DFS找到路径
        unordered_map<string, int> idx;
        int cnt = 0;
        //对应编号
        for (int i = 0; i < equations.size(); i++) {
            if (idx.count(equations[i].first) == 0) {
                idx[equations[i].first] = cnt++;
            }
            if (idx.count(equations[i].second) == 0)
                idx[equations[i].second] = cnt++;
        }        
        vector<int> parent(cnt, 0);
        vector<vector<double> > graph(cnt, vector<double>(cnt, -1));
        //make graph
        //make graph
        for (int i = 0; i < equations.size(); i++) {
            int a = idx[equations[i].first];
            int b = idx[equations[i].second];
            graph[a][b] = values[i];
            graph[b][a] = 1.0 / values[i];
            //cout << graph[b][a];
            //parent[b] = find(a, parent);
        }
        vector<double> ans(queries.size(), 0);
        // find answer
        for (int i = 0; i < queries.size(); i++) {
            if (idx.count(queries[i].first) == 0 
                || idx.count(queries[i].second) == 0)
                ans[i] = -1;
            else if (graph[idx[queries[i].first]][idx[queries[i].second]] != -1)
                ans[i] = graph[idx[queries[i].first]][idx[queries[i].second]];
            else {
                ans[i] = dfs(graph, idx[queries[i].first], idx[queries[i].first], idx[queries[i].second], parent);
                if (ans[i] == 0)
                    ans[i] = -1;
            }
        }
        return ans;
    }



    double dfs(vector<vector<double> >& graph,int src, int a, int b, vector<int>& parent) {
       // cout << graph[a][b] << endl;
        if (a == b)
            return 1;
        for (int i = 0; i < graph[a].size(); i++) {
            if (graph[a][i] != -1  && src != i) {
                double ans = dfs(graph, a, i, b, parent);
                if (ans != 0)
                    return graph[a][i] * ans;
            }
        }
        return 0;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值