leetcode 399

对于每一个等式,都建立两条边,每条边有起点、终点和权值。

每次查询就是找一个从起点到终点的路线,找得到的话就把途径的边的权值累乘。

注意dfs里递归调用dfs的地方,如果下层dfs成功就返回。注意用一个set记录已经访问过的节点,以及回溯时删除set里的节点。

class Solution {
    public double[] calcEquation(List<List<String>> equations, double[] values, List<List<String>> queries) {
        Map<String, Set<Edge>> edgeMap = new HashMap<>();
        for(int i = 0; i < equations.size(); i++){
            String start = equations.get(i).get(0);
            String end = equations.get(i).get(1);
            double value = values[i];

            Set<Edge> edges = edgeMap.getOrDefault(start, new HashSet<>());
            edges.add(new Edge(start, end, value));
            edgeMap.put(start, edges);

            Set<Edge> edges1 = edgeMap.getOrDefault(end, new HashSet<>());
            edges1.add(new Edge(end, start, 1.0 / value));
            edgeMap.put(end, edges1);
        }


        double[] ans = new double[queries.size()];
        for(int i = 0; i < queries.size(); i++){
            ans[i] = dfs(edgeMap, new HashSet<>(), queries.get(i).get(0), queries.get(i).get(1), 1.0);
            //System.out.println(ans[i]);
        }
        return ans;
    }

    private double dfs(Map<String, Set<Edge>> edgeMap, Set<String> visited, String cur, String end, double temp){
        //System.out.println(cur+" "+temp);
        if(!edgeMap.containsKey(cur)){
            return -1.0;
        }
        if(cur.equals(end)){
            return temp;
        }

        visited.add(cur);
        Set<Edge> edges = edgeMap.get(cur);
        for(Edge edge : edges){
            //System.out.println("edge: "+edge);
            if(edge.start.equals(cur)){
                //System.out.println(visited+"   >>");
                //System.out.println(cur+" "+visited.contains(cur));
                if(!visited.contains(edge.end)) {
                    visited.add(edge.end);
                    double nextAns = dfs(edgeMap, visited, edge.end, end, edge.value * temp);
                    if(nextAns != -1.0){
                        return nextAns;
                    }
                    visited.remove(edge.end);
                }
            }
        }
        return -1.0;
    }
}

class Edge {
    String start;
    String end;
    Double value;

    public Edge(String start, String end, double value) {
        this.start = start;
        this.end = end;
        this.value = value;
    }

    @Override
    public int hashCode() {
        return start.hashCode() ^ end.hashCode() ^ value.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        Edge edge = (Edge) obj;
        return this.start.equals(edge.start) && this.end.equals(edge.end) && this.value.equals(edge.value);
    }

    @Override
    public String toString() {
        return "Edge{" +
                "start='" + start + '\'' +
                ", end='" + end + '\'' +
                ", value=" + value +
                '}';
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值