【Graph】399. Evaluate Division(Medium)

#week3#

#from leetcode#

Description


 

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.

 

Analysis


 


题目的意思是给我们一些除法等式,让我们通过这些除法等式来求解其他的一些除法式子,输入有等式集,对应等式的值还有查询的等式集。

那么我们应该如何思考这个问题怎么去解决呢?

答案等式只能够在已知的等式推导出来,我们可能直接通过一个等式得到答案,可能是通过几个等式连在一起除下去得到答案;因此我们可以把这个问题想成一个无向图的问题,每一个变量是图中的一个节点,而每一个等式是图中的路径,路径上的权值则是等式的值,为何要想成无向图而不是有向图呢?因为我们式子可以双向推导,另外实际上我们的无向图路径权值不能够只存一个,需要存v->u的权值,还需要有u->v的权值。

想成图之后,我们重新来思考这个问题,求等式的解,那么就是求图中的一个节点是否能够走到另一个节点,如果可以,并求出它们之间的路径的乘积,所以我们这个问题思路就变得很清晰了,那么我们再考虑需要一些什么集合,边集、点集、还有查询集,我们就将最初的equations作为边集,然后再加上相反的边即可,点集在遍历时构建,然后再写一下算法的大概思路如下:

①遍历equations,加入返回边和权重(权重用values数组存储好即可,下标与equations下标一一对应即可),并且将点加入点集;

②遍历queries:

  对于每个query:

    两点是否在点集中-->no:result=-1,continue继续下一个query;

    -->yes

      两个点是否相同-->yes:result=1,continue继续;

      -->no

        从开始点开始做BFS找去终点的路径,如果能够找到则返回权值,如果不能够则result=-1;

于是就可以愉快地编程了~!其实思路是在不断修补完善中的,最开始有的是一个大致框架,然后写的时候发现一些情况漏掉了,再补上去,才把这个算法补成正确完备的算法。

 

Code


 1 #include<vector>
 2 #include<string>
 3 #include<queue>
 4 #include<iostream>
 5 using namespace std;
 6 class Solution {
 7 private: 
 8     static bool exits(vector<string> vec, string value) {
 9         vector<string>::iterator i;
10         for (i = vec.begin(); i != vec.end(); i++) {
11             if (value == (*i)) return true;
12         }
13         return false;
14     }
15 public:
16     vector<double> calcEquation(vector<pair<string, string>> equations, vector<double>& values, vector<pair<string, string>> queries) {
17         vector<string> points;
18         int size = equations.size();
19         for (int i = 0; i < size; i++) {
20             string firstOne = equations[i].first;
21             string secondOne = equations[i].second;
22             //cout << (exits(points, firstOne)) << exits(points, secondOne);
23             if (!exits(points, firstOne)) points.push_back(firstOne);
24             if (!exits(points, secondOne)) points.push_back(secondOne);
25             equations.push_back(make_pair(secondOne, firstOne));
26             values.push_back(1 / values[i]);
27         }
28 
29         vector<double> result;
30         for (int i = 0; i < queries.size(); i++) {
31             string begin = queries[i].first;
32             string end = queries[i].second;
33         
34             if (!exits(points, begin) || !exits(points, end)) {
35                 result.push_back(-1);
36                 continue;
37             }
38 
39             if (begin == end) {
40                 result.push_back(1);
41                 continue;
42             }
43 
44             queue<string> que;
45             queue<double> weight;
46             vector<string> gone;
47             que.push(begin);
48             weight.push(1);
49             gone.push_back(begin);
50             double temp = -1;
51             while (!que.empty()) {
52                 string point = que.front();
53                 double value = weight.front();
54                 que.pop();
55                 weight.pop();
56                 for (int i = 0; i < equations.size(); i++) {
57                     if (equations[i].first == point) {
58                         if (equations[i].second == end) {
59                             temp = value*values[i];
60                             break;
61                         }
62                         if (!exits(gone, equations[i].second)) {
63                             que.push(equations[i].second);
64                             weight.push(value*values[i]);
65                             gone.push_back(equations[i].second);
66                         }
67                     }
68                 }
69                 if (temp != -1) {
70                     break;
71                 }
72             }
73             result.push_back(temp);
74         }
75         return result;
76     }
77 };

Run Time:0ms(leetcode test)

posted @ 2017-09-24 21:23  小预备  阅读(242)  评论(0编辑  收藏  举报