题解 | #求二叉树的层序遍历#

最小生成树

http://www.nowcoder.com/practice/735a34ff4672498b95660f43b7fcd628

我们采用K算法实现
//步骤:
/**
*1.我们先定义一些基础图结构,图节点(Node),图的边(Edge),图(Graph)
*2.通过二维数组构建我们熟悉的图结构
*3.构建一个堆,以边为单位,每次都取最小边出来,看是否与之前的边构成环,不构成加入
*3.1构建一个并查集合,用来判断是否在形成环:采用集合形式实现
*3.2开始先每个点以自己为节点各成一个集合例如:题目一共A,B, C 三个村庄,开始集合为A->{A},B->{B}, C->{C}
* 当取A->B这条边时:比较A和B的两个集合是否相同,不相同则不会形成环,则将B的集合元素加到A的集合中(合并),同时更新B的集合:A->{A,B},B->{A,B}, C->{C}
*依次往复,
*4.最后将边集合的权值加起来,就是答案

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 返回最小的花费代价使得这n户人家连接起来
     * @param n int n户人家的村庄
     * @param m int m条路
     * @param cost int二维数组 一维3个参数,表示连接1个村庄到另外1个村庄的花费的代价
     * @return int
     */
    public int miniSpanningTree (int n, int m, int[][] cost) {
        // write code here
        //我们采用K算法实现
        //步骤:
        /**
        *1.我们先定义一些基础图结构,图节点(Node),图的边(Edge),图(Graph)
        *2.通过二维数组构建我们熟悉的图结构
        *3.构建一个堆,以边为单位,每次都取最小边出来,看是否与之前的边构成环,不构成加入
        *3.1构建一个并查集合,用来判断是否在形成环:采用集合形式实现
        *4.最后将边集合的权值加起来,就是答案
        */
        //2.
        Graph graph = new Graph(cost);
        //3.
        Queue<Edge> queue= 
            new PriorityQueue<Edge>(/*定义一个比较器*/Comparator.comparingInt(a -> a.weight));//小根堆
        for(Edge edge : graph.edges) {
            queue.add(edge);
        }
        //3.1
        Mysets allsets = new Mysets(graph);
        int miniValue = 0;
        while(!queue.isEmpty()) {
            Edge edge = queue.poll();
            if(!allsets.isSameSet(edge.from, edge.to)){
                allsets.mergeSet(edge.from, edge.to);
                miniValue += edge.weight;
            }
        }
        return miniValue;
    }
    //1.1定义图结构Node
    class Node {
        public int value;//值
        public int in;//入度
        public int out;//出度
        public ArrayList<Node> nexts;//指向的所有节点
        public ArrayList<Edge> myEdges;

        public Node(int value) {
            this.value = value;
            this.in = 0;
            this.out = 0;
            this.nexts = new ArrayList<Node>();
            this.myEdges = new ArrayList<Edge>();
        }
    }
    //1.2定义图结构边Edge
    class Edge {
        public Node from;//开始节点
        public Node to;//结束节点
        public int weight;//权重

        public Edge(int weight, Node from, Node to) {
            this.from = from;
            this.to = to;
            this.weight = weight;
        }
    }
    //1.3定义图结构Graph
    class Graph {
        public HashMap<Integer,Node> nodes;
        public HashSet<Edge> edges;

        public Graph (int [][] array) {
            HashSet<Integer> set = new HashSet<Integer>();
            nodes = new HashMap<Integer,Node>();
            edges = new HashSet<Edge>();
            for(int i = 0; i< array.length; i++) {
                Integer from = array[i][0];
                Integer to = array[i][1];
                int weight = array[i][2];
                //构建nodes
                if(!nodes.containsKey(from)) {
                    nodes.put(from, new Node(from));
                }
                if(!nodes.containsKey(to)) {
                    nodes.put(to, new Node(to));
                }
                //构建edges
                Node fromNode = nodes.get(from);
                Node toNode = nodes.get(to);
                Edge edge = new Edge(weight,fromNode, toNode);
                edges.add(edge);
                //单独处理每个节点
                fromNode.out++;
                fromNode.nexts.add(toNode);
                fromNode.myEdges.add(edge);
                toNode.in++;
            }
        }
    }
    class Mysets {
        public HashMap <Node, ArrayList<Node>> mysets;

        public Mysets(Graph graph) {
            mysets = new HashMap<Node, ArrayList<Node>>();
            for(Node node : graph.nodes.values()) {
                ArrayList<Node> list = new ArrayList<Node>();
                list.add(node);
                mysets.put(node,list);
                ArrayList<Node> list22 = mysets.get(node);
                list.toArray();
            }
        }

        public boolean isSameSet(Node from, Node to) {
            ArrayList<Node> fromlist = mysets.get(from);
            ArrayList<Node> tolist = mysets.get(to);
            return fromlist == tolist;//内存地址相同即可
        }

        public void mergeSet(Node from, Node to) {
            ArrayList<Node> listfrom = mysets.get(from);
            for(Node toNode: mysets.get(to)) {
                listfrom.add(toNode);
                //mysets.put(to, listfrom);//这里写错了toNode不是to,调试大半天
                mysets.put(toNode, listfrom);//将toNode中集合加入from集合中
            }
        }
    }

}
全部评论

相关推荐

看到这个内容真是闹麻了。。。。。。现在有了AI以后很多人面试都会作弊吗?&nbsp;那对老老实实面试的人岂不是不公平....
程序员牛肉:公平那是对小孩子讲的童话故事,成年人的世界只有能不能接受失败的后果。 你要是能接受面试作弊被发现之后多家公司联合永久拉黑的后果,你就搞。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务