LeetCode-algorithms 399. Evaluate Division

本文介绍了一种利用图算法解决变量间比例关系查询的方法。通过构建有向图,将变量作为节点,变量间的比例关系作为带权边,采用改进的Floyd算法计算任意两点间的最短路径,即变量间的比例关系。适用于处理复杂的比例查询问题。
摘要由CSDN通过智能技术生成

题目:

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.

思路:

这道题使用图去做会比较简单,每一个变量就是图上的点,而两个变量之间的倍数关系就是边,在这里很明显是有向图,因为边A->B与边B->A是两个不同的值。

那么思路很简单,我们只需要计算每个点到它所能到达的点的路径长度即可。需要注意的是这里的路径长度是累乘的关系。由于这个图里面的路径长度是固定的,我们可以

修改一下floyd算法,不需要判断路径从K点经过是否会变小,而是路径是否从K点经过可达,这样就能计算出路径的长度。开始的时候根据已知的条件,把邻接矩阵填好,自己

与自己的长度为1,与不可达的点长度为-1,这样只需要判断点A与点C不可达,并且点A与点B可达,点B与点C可达,即可计算出点A到点C的距离为(AB)*(BC)。

代码:

class Solution {
public:
	vector<double> calcEquation(vector<pair<string, string>> equations, vector<double>& values, vector<pair<string, string>> queries) {
		set<string> var;
		string first, second;
		map<string, int> m;
		vector<double> result;
		int i = 0, j,k, first_index, second_index;
		for (pair<string, string> tp : equations){
			var.insert(tp.first);
			var.insert(tp.second);
		}
		
		for (set<string>::iterator it = var.begin(); it != var.end(); it++){
			m[*it] = i++;
		}
		vector<vector<double>> A(var.size(),vector<double>(var.size()));
		for (i = 0; i < var.size(); i++){
			for (j = 0; j < var.size(); j++){
				A[i][j] = i == j ? 1 : -1;
			}
		}
		for (i = 0; i < equations.size(); i++){
			first = equations[i].first;
			second = equations[i].second;
			first_index = m.find(first)->second;
			second_index = m.find(second)->second;
			A[first_index][second_index] = values[i];
			A[second_index][first_index] = 1.0/values[i];
		}
		for (k = 0; k < var.size(); k++){
			for (i = 0; i < var.size(); i++){
				for (j = 0; j < var.size(); j++){
					if (A[i][j] < 0 && A[i][k]>0 && A[k][j] >0){
						A[i][j] = A[i][k] * A[k][j];
						A[j][i] = 1.0 / A[i][j];
					}
				}
			}
		}
		map<string, int>::iterator fi, si;
		for (pair<string, string> tp : queries){
			first = tp.first;
			second = tp.second;
			fi = m.find(first);
			si = m.find(second);
			if (fi == m.end() || si == m.end()){
				result.push_back(-1);
			}
			else{
				result.push_back(A[fi->second][si->second]);
			}
		}
		return result;
	}
};

结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值