题目描述:
给出方程式 A / B = k, 其中 A 和 B 均为代表字符串的变量, k 是一个浮点型数字。根据已知方程式求解问题,并返回计算结果。如果结果不存在,则返回 -1.0。
示例 :
给定 a / b = 2.0, b / c = 3.0
问题: a / c = ?, b / a = ?, a / e = ?, a / a = ?, x / x = ?
返回 [6.0, 0.5, -1.0, 1.0, -1.0 ]
输入为: vector<pair<string, string>> equations, vector& values, vector<pair<string, string>> queries(方程式,方程式结果,问题方程式), 其中 equations.size() == values.size(),即方程式的长度与方程式结果长度相等(程式与结果一一对应),并且结果值均为正数。以上为方程式的描述。 返回vector类型。
基于上述例子,输入如下:
equations(方程式) = [ [“a”, “b”], [“b”, “c”] ],
values(方程式结果) = [2.0, 3.0],
queries(问题方程式) = [ [“a”, “c”], [“b”, “a”], [“a”, “e”], [“a”, “a”], [“x”, “x”] ].
输入总是有效的。你可以假设除法运算中不会出现除数为0的情况,且不存在任何矛盾的结果。
使用带权的LRU
有点难懂…
class Solution {
Map<String, String> parents = new HashMap<>();
Map<String, Double> vals = new HashMap<>();
public double[] calcEquation(List<List<String>> equations, double[] values, List<List<String>> queries) {
double[] res = new double[queries.size()];
for (int i = 0; i < values.length; i++) {
union(equations.get(i).get(0), equations.get(i).get(1), values[i]);
}
for (int i = 0; i < queries.size(); i++) {
String x = queries.get(i).get(0);
String y = queries.get(i).get(1);
res[i] = (parents.containsKey(x) && parents.containsKey(y) && find(x) == find(y)) ? vals.get(x) / vals.get(y) : -1.0;
}
return res;
}
private void add(String s) {
if (parents.containsKey(s)) {
return;
}
parents.put(s, s);
vals.put(s, 1.0);
}
private String find(String s) {
String p = parents.getOrDefault(s, s);
if (s != p) {
String pp = find(p);
vals.put(s, vals.get(s) * vals.get(p));
parents.put(s, pp);
}
return parents.getOrDefault(s, s);
}
private void union(String x, String y, double v) {
add(x);
add(y);
String px = find(x);
String py = find(y);
parents.put(px, py);
vals.put(px, v * vals.get(y) / vals.get(x));
}
}
或者使用图,转成dfs
代码:
class Solution {
// 使用dfs
// map记录各个索引
Map<String, Integer> map = new HashMap<>();
int index = 0;
// 构建图形,graph[][] 表示从i/j的值
double [][] graph;
public double[] calcEquation(List<List<String>> equations, double[] values, List<List<String>> queries) {
for (List<String> list : equations) {
String str1 = list.get(0);
String str2 = list.get(1);
if(!map.containsKey(str1)){
map.put(str1, index ++);
}
if(!map.containsKey(str2)){
map.put(str2, index ++);
}
}
double result[] = new double[queries.size()];
Arrays.fill(result, -1.0);
graph = new double[index][index];
for (int i = 0; i < values.length; i++) {
List<String> list = equations.get(i);
String str1 = list.get(0);
String str2 = list.get(1);
graph[map.get(str1)][map.get(str2)] = values[i];
graph[map.get(str2)][map.get(str1)] = 1 / values[i];
}
for (int i = 0; i < queries.size(); i++) {
List<String> list = queries.get(i);
String tem1 = list.get(0);
String tem2 = list.get(1);
if(!map.containsKey(tem1) || !map.containsKey(tem2)){
continue;
}
if(tem1.equals(tem2)){
result[i] = 1.0;
continue;
}
int index1 = map.get(tem1);
int index2 = map.get(tem2);
boolean [] visited = new boolean[index];
dfs(i,result,1.0, visited, index1, index2, graph);
}
return result;
}
public void dfs(int k,double[]result,double len,boolean visited[],int start,int end,double [][] graph){
if(graph[start][end] != 0){
result[k] = len * graph[start][end];
}else {
for (int i = 0; i < index; i++) {
if(!visited[i] && graph[start][i] != 0){
visited[i] = true;
dfs(k,result,len * graph[start][i], visited, i, end, graph);
visited[i] = false;
}
}
}
}
}