剑指offer 专项突破版 111、计算除法

题目链接

思路
  • 这个题可以看作一个寻找路径的问题~
  • 我们把所有出现的数字看作一个结点 那么这道题算除法就是让我们找到两个结点间的路径积是多少 而且有向图的边是有权重的,因此可以看作一个有向网~
  • 注意两个结点 如果E(a,b) = m 则E(b,a) = 1/m
  • 还有一点在于 E(a,b)表示a/b,如果我们要找a/c 我们可以找到a/b,然后再找到b/c,这两个结果应该做乘法,所以求的是路径积
  • 最后是如何表示图?我们可以用一个Map来表示结点和边的映射,具体的value还是一个Map,是临近节点和权重的映射
    Map<String,Map<String,Double>> graph
  • 此题为了防止重复搜索,仍然需要visited集合 一定要仔细阅读dfs代码,这里更像是回溯法
  • 这样处理visited是因为,如果某一步我从[1]搜寻到[234],然后又通过[2]搜索到了[5],如果不在递归函数结束时清除[5]的visited状态,那么我们便无法通过[34]还有[1]再搜索到5,因此会漏掉情况!!
class Solution {
    public double[] calcEquation(List<List<String>> equations, double[] values, List<List<String>> queries) {
		
        // 根据前两个参数构建图
        Map<String,Map<String,Double>> graph = new HashMap<>();
		for(int i = 0 ; i < equations.size() ; i++){
            List<String> equation = equations.get(i);
            String s1 = equation.get(0) , s2 = equation.get(1);
            Map<String,Double> map1 = graph.getOrDefault(s1,new HashMap<>()),
								map2 = graph.getOrDefault(s2,new HashMap<>());
            map1.put(s2,values[i]);
            map2.put(s1,1/values[i]);

            graph.put(s1,map1);
            graph.put(s2,map2);
        }

		double[] result = new double[queries.size()];
        Set<String> visited = new HashSet<>();

        for(int i = 0 ; i < queries.size() ; i++){
            List<String> query = queries.get(i);
            result[i] = dfs(graph,query.get(0),query.get(1),1,new HashSet<>());
        }

        return result;
    }
	

    // 根据建好的图搜索结果
    private double dfs(Map<String,Map<String,Double>> graph , String dividend , String dividor , double val ,Set<String> visited){
		if(!graph.containsKey(dividend) || !graph.containsKey(dividor))
        	return -1.0;
		if(dividend.equals(dividor))
        	return 1.0;
		if(graph.get(dividend).containsKey(dividor))
        	return val * graph.get(dividend).get(dividor);
		
        visited.add(dividend);
        for(Map.Entry<String,Double> entry : graph.get(dividend).entrySet()){
            String key = entry.getKey();
            if(!visited.contains(key)){
            	double nowVal = dfs(graph,entry.getKey(),dividor,val*entry.getValue(),visited);
            	if(-1 != nowVal)
            		return nowVal;
            }
        }
		
        visited.remove(dividend);
        return -1.0;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值