zoukankan      html  css  js  c++  java
  • 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.

    Notice

    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.

    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.

    首先看下树的定义:详见维基百科,只要没有回路连通图就是树.

    如果无向简单图G有有限个顶点(设为n个顶点),那么G 是一棵还等价于:G是连通的,有n − 1条边,并且G没有简单回路.

    后面这条定义更加关键, 也就是说我们先判断是不是有n-1边,不是则肯定没法构成树.

    之后我们判断是否有简单回路.有回路,则肯定所有节点之间不是全部联通的.可以中途退出.

    如何判断是否有回路呢,可以使用并查集,在并查集中,所有联通的块都有同一个祖先节点.如果新加入的这条边,两个节点的祖先节点一样,说明已经联通,会构成环,则说明不合格.

    并查集大小是n,合并和查找操作O(n)级别的,所以最终代码时间复杂度为O(nlog*n)级别的,也就是O(n)级别.另外这题顶点已经预先给定,所以用数组是一个比hashmap更节省空间的选择.

    代码如下:

    class Solution:
        # @param {int} n an integer
        # @param {int[][]} edges a list of undirected edges
        # @return {boolean} true if it's a valid tree, or false
        def validTree(self, n, edges):
            if not n:
                return True
            if n - 1 != len(edges):
                return False
            UF = UnionFind(n)
            for edge in edges:
                if UF.find(edge[0]) == UF.find(edge[1]):
                    return False
                UF.union(edge[0], edge[1])
            return True 
    class UnionFind(object):
        def __init__(self, n):
            self.id = range(n)
            self.sz = [1] * n
            
        def union(self, x, y):  # union is carried out between fathers
            i = self.find(x)
            j = self.find(y)
            if self.sz[i] > self.sz[j]:
                i, j = j, i
            self.id[j] = i
            self.sz[i] += self.sz[j]
            
        def find(self, i):
            while i != self.id[i]:
                self.id[i] = self.id[self.id[i]]
                i = self.id[i]
            return i
                
  • 相关阅读:
    c#中ref与out区别
    【转载】Firebug中net面板的使用
    结构声明、定义
    开始旅程了
    strcpy、strcat、strcmp、strlen
    #include 格式
    宏定义
    MySQL 字段类型
    MySQL 约束类型
    (转载)C#语言之“string格式的日期时间字符串转为DateTime类型”的方法
  • 原文地址:https://www.cnblogs.com/sherylwang/p/5639001.html
Copyright © 2011-2022 走看看