题解 | #牛群之间的体重比#

牛群之间的体重比

https://www.nowcoder.com/practice/75717e3241704b55a71ecc6bdbf6b9b4

知识点:Hash,有向图的邻接表存储和遍历DFS

文字分析(绘图辅助理解)

唯一编号:体重比weightRatios[][]和ratioValues[]

对应关系: weightRatios[i]=[Ai,Bi] Ai/Bi=ratioValues[i]

要求结果: questions[j] = [Cj,Dj] 求Cj/Dj = ?

总结:由已知的体重比求未知的体重比,无法求得的使用-1.0表示

[["a","b"],["b","c"],["c","d"]],[2.0,3.0,4.0],[["a","d"],["b","d"],["a","c"],["d","a"]]

以示例二的数据为例

有向图:其中正向数据为题给参数,反向数据自行添加

邻接表:

DFS:目标是计算两个联通结点之间的权重积,故采用深度遍历

使用语言:Java

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 唯一编号:体重比weightRatios[][]和ratioValues[]
     * weightRatios[i]=[Ai,Bi] Ai/Bi=ratioValues[i]
     * questions[j] = [Cj,Dj] 求Cj/Dj = ?
     * 总结:由已知的体重比求未知的体重比,无法求得的使用-1.0表示
     * @param weightRatios string字符串二维数组 
     * @param ratioValues double浮点型一维数组 
     * @param questions string字符串二维数组 
     * @return double浮点型一维数组
     */
    public double[] calcWeightRatios (String[][] weightRatios, double[] ratioValues, String[][] questions) {
            Map<String,Map<String,Double>> graph = buildGraph(weightRatios,ratioValues);

            double[] answers = new double[questions.length];

            /**
            * 遍历问题数组
            */
            for(int i=0;i<questions.length;i++){
                //将前一个编号作为开始结点,后一个编号作为结束结点
                //此时按照顺序一路相乘得到的数即为需要的体重比
                String starNode = questions[i][0];
                String endNode = questions[i][1];
                //不包含任意一个结点,都得不到需要的体重比数据
                if(!graph.containsKey(starNode)||!graph.containsKey(endNode)){
                    answers[i] = -1.0;
                    continue;
                }
                //构造set集合作为遍历标记
                Set<String> visited = new HashSet<>();
                //dfs遍历
                double result = dfs(graph,starNode,endNode,1.0,visited);
                answers[i] = result;
            }
            return answers;
    }


    /**
    * 构造有向图
    * 邻接表存储
    */
    private Map<String,Map<String,Double>> buildGraph(String[][] weightRatios,double[] ratioValues){
        Map<String,Map<String,Double>> graph = new HashMap<>();

        /**
        * 将已有的体重比存入邻接表
        * 正向value = weightRatio
        * 反向value = 1.0/weightRatio
        */
        for(int i=0;i<weightRatios.length;i++){
            String sourceNode = weightRatios[i][0];
            String targetNode = weightRatios[i][1];
            double weightRatio = ratioValues[i];

            // 若key存在,返回已有的value,否则存入,返回空
            graph.putIfAbsent(sourceNode,new HashMap<>());
            graph.get(sourceNode).put(targetNode,weightRatio);

            graph.putIfAbsent(targetNode,new HashMap<>());
            graph.get(targetNode).put(sourceNode,1.0/weightRatio);
        }
        return graph;
    }


    private double dfs(Map<String,Map<String,Double>> graph,String curNode,String endNode,double value,Set<String> visited){
        //当前结点为最终结点时,返回结果
        if(curNode.equals(endNode)){
            return value;
        }
        //添加遍历标记
        visited.add(curNode);
        //判空
        if(!graph.containsKey(curNode)){
            return -1.0;
        }
        //遍历邻接表
        for(Map.Entry<String,Double> neighbor:graph.get(curNode).entrySet()){
            String nextNode = neighbor.getKey();
            double weightRatio = neighbor.getValue();

            if(!visited.contains(nextNode)){
                double result = dfs(graph,nextNode,endNode,value*weightRatio,visited);
                if(result!= -1.0){
                    return result;
                }
            }
        }
        return -1.0;
    }
}

面试高频TOP202 文章被收录于专栏

面试高频TOP202题解

全部评论

相关推荐

一颗宏心:华为HR晚上过了十二点后还给我法消息。
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务