Force buckle - Sword finger Offer II 111 Calculate division (Figure + BFS)

Posted by Joe689 on Tue, 25 Jan 2022 21:57:16 +0100

Given a variable pair array equations and a real value array values as known conditions, where equations[i] = [Ai, Bi] and values[i] jointly represent the equation Ai / Bi = values[i]. Each Ai or Bi is a string representing a single variable.

There are also some problems represented by array queries, where queries[j] = [Cj, Dj] represents the j-th problem. Please find Cj / Dj =? As the answer.

Return answers to all questions. If there is an uncertain answer, replace it with - 1.0. If there is a string in the question that does not appear in the given known conditions, you also need to replace the answer with - 1.0.

Note: input is always valid. It can be assumed that there will be no divisor of 0 in the division operation, and there are no contradictory results.

Example 1:

Input: equations = [["a", "b"], ["b", "c"]], values = [2.0,3.0], queries = [["a", "c"], ["b", "a"], ["a", "e"], ["a", "a"], ["x", "x"]]
Output: [6.00000,0.50000, - 1.00000,1.00000, - 1.00000]
Explanation:
Conditions: a / b = 2.0, b / c = 3.0
Question: A / C =?, b / a = ?, a / e = ?, a / a = ?, x / x = ?
Result: [6.0, 0.5, - 1.0, 1.0, - 1.0]
Example 2:

Input: equations = [["a", "b"], ["b", "c"], ["bc", "cd"]], values = [1.5,2.5,5.0], queries = ["a", "c"], ["c", "b"], ["bc", "cd"], ["cd", "bc"]]
Output: [3.75000,0.40000,5.00000,0.20000]
Example 3:

Input: equations = [["a", "b"]], values = [0.5], queries = [["a", "b"], ["b", "a"], ["a", "c"], ["x", "y"]]
Output: [0.50000,2.00000, - 1.00000, - 1.00000]

Tips:

1 <= equations.length <= 20
equations[i].length == 2
1 <= Ai.length, Bi.length <= 5
values.length == equations.length
0.0 < values[i] <= 20.0
1 <= queries.length <= 20
queries[i].length == 2
1 <= Cj.length, Dj.length <= 5
AI, Bi, CJ and DJ are composed of lowercase English letters and numbers

Problem solving ideas

Time 0ms, easy thinking, laborious map construction, two-way weighted map

The string of this question is actually useless. It's just a code, so just give him a code;
In the first traversal, record all variables with known information with hash set, and establish a hash table mapping stoid from string to number;
In the second traversal, the known information is stored in the graph, and the data structure vector < unordered such as hash table array is adopted_ map<string, double> > linkļ¼›
From the first string to number mapping, the mapping of divisor and value can be stored under the subscript of the divisor;
For example, if a / b = 1.5 and the corresponding number of a is 0, then link[0] stores all the known information that the divisor is a, including the mapping from B to 1.5;
At the same time, the graph is bidirectional, b/a = 1/1.5, and the graph is built synchronously;

For each query, if the target is not present, the corresponding result is - 1.0. If the divisor is the same, the corresponding result is 1.0;
Except for special cases, it is necessary to find the connection relationship of BFS in the figure:
For example, if a/b = 1.5 and b/c = 2, find a - > b - > C in the graph, and the corresponding result is the multiplication of edge weights;
The product of variables and weights from the starting point to the current position is stored in the queue, and a hash set is used to record the visited nodes to avoid repeated invalid access;

code

class Solution {
private:
    vector<unordered_map<string, double> > link;
    unordered_map<string, int> stoid;
public:
    double com(string a, string b) {
        queue<pair<string, double> > q;
        unordered_set<string> vis;
        vis.insert(a);
        q.push({a,1.0});
        while(!q.empty()) {
            auto [s, val] = q.front();
            q.pop();
            if(s == b) return val;
            for(auto [nexts, nextval] : link[stoid[s]]) {
                if(!vis.count(nexts)) {
                    vis.insert(nexts);
                    q.push({nexts, val * nextval});
                }
            }
        }
        return -1.0;      
    }
    vector<double> calcEquation(vector<vector<string>>& equations, vector<double>& values, vector<vector<string>>& queries) {
        unordered_set<string> words;
        int id = 0;
        for(auto e : equations) {
            for(int i = 0; i < 2; i++) {
                if(!words.count(e[i])) {
                    words.insert(e[i]);
                    stoid[e[i]] = id;
                    id++;
                }
            }
        }
        link = vector<unordered_map<string, double> >(id);
        for(int i = 0; i < equations.size(); i++) {
            string a = equations[i][0], b = equations[i][1];
            link[stoid[a]][b] = values[i];
            link[stoid[b]][a] = (double) 1 / values[i];
        }
        int n = queries.size();
        vector<double> ans(n);
        for(int i = 0; i < n; i++) {
            string a = queries[i][0], b = queries[i][1];
            if(!words.count(a) || !words.count(b)) ans[i] = -1.0;
            else if(a == b) ans[i] = 1.0;
            else {
                ans[i] = com(a, b);
            }
        }
        return ans;
    }
};

Topics: Algorithm leetcode