zoukankan      html  css  js  c++  java
  • 261.Graph Valid Tree

    题目描述:

    Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), write a function to check whether these edges make up a valid tree.

    For example:

    Given n = 5 and edges = [[0, 1], [0, 2], [0, 3], [1, 4]], return true.

    Given n = 5 and edges = [[0, 1], [1, 2], [2, 3], [1, 3], [1, 4]], return false.

    Note: you can assume that no duplicate edges will appear in edges. Since all edges are undirected, [0, 1] is the same as [1, 0] and thus will not appear together in edges.

    解题思路:

    判断给出的点和边构成的图是否为一个树,可以认为是判断图中有无环的存在,可以使用并查集(union find)来进行解答。

    本题中的图为无向图, 即[0,1]和[1,0]为同一条边,为了方便寻找唯一根结点,在union的过程中,将值较大的父亲值设置为值较小的父亲,即:

    if(a < b) parent[rootB] = rootA; else parent[rootA] = rootB;

     

    我遇见的bug:

    1. 边界问题检测:题目要求为能否构成一棵有效的树,若边集为空,有以下情况:
      • 只有一个节点:可以构成一棵有效的树
      • 有一个以上的节点:因为没有边。所以存在离散的节点,所以不能构成一棵有效的树
      • 没有节点:空树
    2. 如果存在n个节点,若要把n个节点连接起来,至少需要n-1条边。若边的条数少于n-1,则无法链接所有节点,不能构成一颗有效的树
    public class Solution {
        /**
         * @param n: An integer
         * @param edges: a list of undirected edges
         * @return: true if it's a valid tree, or false
         */
        public boolean validTree(int n, int[][] edges) {
            // write your code here
            if(edges.length == 0 && n > 1)
                return false;
            if(n == 0 || (edges.length == 0 && n == 1))
                return true;
            if(edges.length < n-1)
                return false;
            int[] parent = new int[n];
            for(int i = 0; i < n; i++){
                parent[i] = i;
            }
            for(int i = 0; i < edges.length; i++){
                if(!union(parent, edges[i][0], edges[i][1]))
                    return false;
                
            }
            int root = find(parent, 0);
            for(int i = 0; i < n; i++){
                if(find(parent, i) != root)
                    return false;
            }
            return true;
        }
        private int find(int[] parent, int a){
            if(parent[a] == a)
                return a;
            return parent[a] = find(parent, parent[a]);
        }
        private boolean union(int[] parent, int a, int b){
            int rootA = find(parent, a);
            int rootB = find(parent, b);
            if(rootA != rootB){
                if(a < b)
                    parent[rootB] = rootA;
                else
                    parent[rootA] = rootB;
                return true;
            }
            return false;
        }
    }

    突然想到:

    当边数等于n-1时,可能出现一棵有效的树,此时无环,若存在环,则一定有孤立的点。

    当边数大于n-1时,一定有环出现。

    所以上面代码应该可以更简洁一点?

  • 相关阅读:
    Arraw function
    constructor&object 的联系与对比
    for each in&for in&for of
    编程历史
    正则表达式
    DOM&BOM
    关于码云0095的一篇文章。
    vue2路由导航守卫(钩子函数)
    原声ajax请求数据
    express 创建项目
  • 原文地址:https://www.cnblogs.com/yaoyudadudu/p/8732302.html
Copyright © 2011-2022 走看看