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
                
  • 相关阅读:
    微信小程序,答题问卷,单选,多选混合在一个借口,前端怎么循环
    react 从0到1
    react从0到0
    es6 系统总结
    点击页面的某个元素,弹出这个元素的索引(是第几个)
    js return的用法
    安装golang.org/x/*
    完美解决从github上下载东西慢的方法
    初探golang和应用其框架 gin 的 使用教程(一)安装篇
    CentOS7安装go开发环境
  • 原文地址:https://www.cnblogs.com/sherylwang/p/5639001.html
Copyright © 2011-2022 走看看