399. Evaluate Division

https://leetcode.com/problems/evaluate-division/
输入为:

equations = [ ["a", "b"], ["b", "c"] ],
values = [2.0, 3.0],

要求输出为:

queries = [ ["a", "c"], ["b", "a"], ["a", "e"], ["a", "a"], ["x", "x"] ]. 
ans = [6.0,3.0,-1.0,1.0,-1.0]

有两种做法:
建图法,后BFS搜索;这种方法建图方法简单耗时少,但查询耗时长;

class Solution {
    public double[] calcEquation(String[][] equations, double[] values, String[][] queries) {
        HashMap<String, Node> graph = buildGraph(equations, values);
        double[] ans = new double[queries.length];
        for(int j = 0; j < queries.length; j++){
            String node1 = queries[j][0];
            String node2 = queries[j][1];
            if(!graph.containsKey(node1) || !graph.containsKey(node2)){
                ans[j] = -1.0d;
            }
            else{
                ans[j] = graphFind(graph.get(node1), graph.get(node2));
            }
        }
        return ans;
    }

    private double graphFind(Node start, Node end){
        Set<String> visited = new HashSet<>();
        Queue<Node> nodeQ = new LinkedList<>();
        Queue<Double> distance = new LinkedList<>();
        nodeQ.add(start);
        distance.add(1.0d);
        while(nodeQ.size() > 0){
            Node tmp = nodeQ.poll();
            double dis = distance.poll();
            if(tmp.name.equals(end.name)){
                return dis;
            }
            for(Node node: tmp.getMap().keySet()){
                if(!visited.contains(node.name)){
                    nodeQ.add(node);
                    distance.add(dis * tmp.getMap().get(node));
                    visited.add(node.name);
                }
            }

        }
        return -1.0d;
    }

    class Node{
        String name;
        HashMap<Node, Double> map;
        public Node(String name){
            this.name = name;
            this.map = new HashMap<>();
        }

        private void assign(Node node, double dis){
            this.map.put(node, dis);
        }

        HashMap<Node, Double> getMap(){
            return this.map;
        }
    }

    private HashMap<String, Node> buildGraph(String[][] equations, double[] values){
        HashMap<String, Node> graph = new HashMap<>();
        for(int i = 0; i < equations.length; i++){
            String node1 = equations[i][0];
            String node2 = equations[i][1];
            if(!graph.containsKey(node1)){
                graph.put(node1, new Node(node1));
            }
            if(!graph.containsKey(node2)){
                graph.put(node2, new Node(node2));
            }
            graph.get(node1).assign(graph.get(node2), values[i]);
            graph.get(node2).assign(graph.get(node1), 1.0d/values[i]);
        }
        return graph;
    }
}

建表法,将所有可能的结果存储进HashMap,建表耗时长,查询耗时短(仅为O(1));

class Solution {
    public double[] calcEquation(String[][] equations, double[] values, String[][] queries) {
        if(equations.length == 0){return values;}
        List<HashMap<String, Double>> valueMap = new ArrayList<HashMap<String, Double>>();
        // valueMap.add(new HashMap<String, Double>());
        for(int i=0; i < equations.length; i++){
            boolean flag = false;
            for(HashMap<String, Double> tmp: valueMap){
                if(tmp.containsKey(equations[i][0])){
                    System.out.println(tmp.get(equations[i][0]).getClass().getName());
                    tmp.put(equations[i][1], (tmp.get(equations[i][0]).doubleValue() / values[i]));
                    flag = true;
                    break;
                }
                else if(tmp.containsKey(equations[i][1])){
                    tmp.put(equations[i][0], (tmp.get(equations[i][1]).doubleValue() * values[i]));
                    flag = true;
                    break;
                }
            }
            if(!flag){
                HashMap<String, Double> newMap = new HashMap<>();
                newMap.put(equations[i][1], 1.0d);
                newMap.put(equations[i][0], values[i]);
                valueMap.add(newMap);
            }
        }
        // System.out.println(valueMap.size());
        // for(HashMap tmp: valueMap){
        //     System.out.println(tmp);
        // }
        
        
        combineMap(valueMap);
        double[] ans = new double[queries.length];
        int mapLength = valueMap.size();
        for(int i = 0; i < queries.length; i++){
            boolean getValue = false;
            for(int j = 0; j < mapLength; j++){
                if(valueMap.get(j).containsKey(queries[i][0]) && valueMap.get(j).containsKey(queries[i][1])){
                    ans[i] = valueMap.get(j).get(queries[i][0])/ valueMap.get(j).get(queries[i][1]);
                    getValue = true;
                }
            }
            if(!getValue){
                ans[i] = -1.0d;
            }

//            if(valueMap.get(0).containsKey(queries[i][0]) && valueMap.get(0).containsKey(queries[i][1])){
//                ans[i] = valueMap.get(0).get(queries[i][0])/ valueMap.get(0).get(queries[i][1]);
//            }
//            else{
//                ans[i] = -1.0d;
//            }
        }
        return ans;
    }
    
    private void combineMap(List<HashMap<String, Double>> listMap){
        Set<Integer> skip = new HashSet<>();
        for(int i = 0; i < listMap.size(); i++){
            if(skip.contains(i)){
                continue;
            }
            for(int j = i; j < listMap.size(); j++){
                if(skip.contains(j)){
                    continue;
                }
                if(combineMapHelper(listMap, i,j)){
                    skip.add(j);
                }
            }
        }
        List<Integer> array = new ArrayList<>();
        for(int i : skip){
            array.add(i);
        }
        Collections.sort(array, Collections.reverseOrder());
        for(int j = 0; j < array.size(); j++){
            listMap.remove(array.get(j));
        }
    }

    private boolean combineMapHelper(List<HashMap<String, Double>> listMap, int i, int j){
        HashMap<String, Double> map1 = listMap.get(i);
        HashMap<String, Double> map2 = listMap.get(j);
        Set<String> set1 = map1.keySet();
        Set<String> set2 = map2.keySet();
        String pointer = "";
        for(String tmp: set1){
            if(set2.contains(tmp)){
                pointer = tmp;
                break;
            }
        }
        if(pointer == ""){
            return false;
        }
        for(String tmp: set2){
            map1.put(tmp, (map1.get(pointer).doubleValue()/map2.get(pointer).doubleValue())*map2.get(tmp));
        }
        return true;
    }
    
//     private void combineMap(List<Map<String, Integer>> listMap){
//         if(listMap.size() == 0){
//             return listMap;
//         }
        
//     }
}

代码都比较繁琐,也都涉及到非常多的语法问题;之后有时间再来修缮。

    原文作者:萧瑟空间
    原文地址: https://www.jianshu.com/p/78a3565121ca
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞