Leetcode 399 Evaluate Division

题意

给定一系列除法等式,比如a/b = 3, b/c = 2, 有一个query array,求诸如a/c 的答案

链接

https://leetcode.com/problems/evaluate-division/

思考

诸如a/b = 3, b / c = 2的等式实际上可以转化成图,a, b, c为顶点,a->b = 3, b -> c = 2, b -> a = 1/3, c->b = 1/2, 比如a/c其实就是在求a->c的权重是多少

题解

建立一个邻接矩阵,包含每个顶点到每个顶点的权重,用dfs搜索路径并把路径的权重相乘

解法

DFS

class Solution {
public:
    unordered_map <string, vector<pair<string, double>>> g;
    vector<double> calcEquation(vector<vector<string>>& equations, vector<double>& values, vector<vector<string>>& queries) {
        vector<double> res;
        for(int i = 0; i < equations.size(); i++) {
            string a = equations[i][0];
            string b = equations[i][1];
            double val1 = values[i];
            double val2 = 1/values[i];
            g[a].push_back({b, val1});
            g[b].push_back({a, val2});
        }

        for(auto& query: queries) {
            string a = query[0];
            string b = query[1];
            if(!g.count(a) || !g.count(b)) {
                res.push_back(-1.0);
                continue;
            }
			//防止dfs遍历已经遍历过的节点,防止死循环
            unordered_set<string> st;
            res.push_back(dfs(a, b, st));
        }
        return res;
    }
	//a是起点,b是终点
    double dfs(string& a, string& b , unordered_set<string>& st) {
        if(a == b) return 1.0;
        st.insert(a);
        for(auto& [neigh, val]: g[a]) {
            if(!st.count(neigh)) {
                auto res = val * dfs(neigh, b, st);
                //这里判断res而不是val,因为dfs如果没有搜索到一条路径,那么就会返回-1.0,负数的话就不管,搜索下一条可行的路径
                if(res > 0) {
                    return res;
                }
            }
        }
        return -1.0;
    }
};

BFS

class Solution {
public:
    unordered_map<string, vector<pair<string, double>>> g;
    vector<double> calcEquation(vector<vector<string>>& equations, vector<double>& values, vector<vector<string>>& queries) {
        //construct a graph
        vector<double> res;
        for(int i = 0; i < equations.size(); i++) {
            vector<string> v = equations[i];
            double val1 = values[i];
            double val2 = 1.0/values[i];
            g[v[0]].push_back({v[1], val1});
            g[v[1]].push_back({v[0], val2});
        }

        for(auto& query: queries) {
            unordered_set<string> st;
            res.push_back(cal(query, st));
        }
        return res;
    }

    double cal(vector<string>& query, unordered_set<string>& st) {
        double res = -1;
        queue<pair<string, double>> q;
        if(!g.count(query[0])) {
            return -1.0;
        }
        q.push({query[0], 1});
        st.insert(query[0]);

        while(q.size()) {
            pair<string, double> node = q.front();
            q.pop();
            if(node.first == query[1]) {
                return node.second;
            }
            for(auto& e: g[node.first]) {
                if(!st.count(e.first)) {
                    st.insert(e.first);
                    q.push({e.first, e.second * node.second});
                }
            } 
        }
        return -1.0;
    }
};

时间复杂度: O ( V + E ) O(V+E) O(V+E) V是图的顶点数E是图的边数
空间复杂度: O ( 图 + E ) O(图+E) O(+E)

对于这道题而言,bfs会相对比较慢,因为他要维护更多的状态(维护起点到某个点的权重)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值