LeetCode 题解(246) : 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]], returntrue.

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

Hint:

  1. Given n = 5 andedges = [[0, 1], [1, 2], [3, 4]], what should your return? Is this case a valid tree?
  2. According to the definition of tree on Wikipedia: “a tree is an undirected graph in which any two vertices are connected byexactly one path. In other words, any connected graph without simple cycles is a tree.”

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.

题解:

最简便的写法是Quick-Union,参见Coursera Algorithm Part I.

但效率未必是最高的,因为如果数据量很大的时候,寻找parent会很费时。

Python直接用Set求解效率也近似。

C++版:

class Solution {
public:
    bool validTree(int n, vector<pair<int, int>>& edges) {
        vector<int> root(n, -1);
        for(int i = 0; i < edges.size(); i++) {
            int root1 = find(root, edges[i].first);
            int root2 = find(root, edges[i].second);
            if(root1 == root2)
                return false;
            root[root1] = root2;
        }
        return edges.size() == n - 1;
    }
    
    int find(vector<int> &root, int e) {
        if(root[e] == -1)
            return e;
        else
            find(root, root[e]);
    }
};

Java版:

public class Solution {
    public boolean validTree(int n, int[][] edges) {
        int[] root = new int[n];
        for(int i = 0; i < n; i++)
            root[i] = i;
        for(int i = 0; i < edges.length; i++) {
            int root1 = find(root, edges[i][0]);
            int root2 = find(root, edges[i][1]);
            if(root1 == root2)
                return false;
            root[root2] = root1;
        }
        return edges.length == n - 1;
    }
    
    private int find(int[] root, int e) {
        if(root[e] == e)
            return e;
        else
            return find(root, root[e]);
    }
}

Python版 Quick-Union:

class Solution(object):
    def validTree(self, n, edges):
        """
        :type n: int
        :type edges: List[List[int]]
        :rtype: bool
        """
        root = [i for i in range(n)]
        for i in edges:
            root1 = self.find(root, i[0])
            root2 = self.find(root, i[1])
            if root1 == root2:
                return False
            else:
                root[root1] = root2
        return len(edges) == n - 1
        
    def find(self, root, e):
        if root[e] == e:
            return e
        else:
            return self.find(root, root[e])

Python版 Set:

class Solution(object):
    def validTree(self, n, edges):
        """
        :type n: int
        :type edges: List[List[int]]
        :rtype: bool
        """
        if n == 1:
            return True
            
        if len(edges) == 0 or len(edges) < n - 1:
            return False    
        s = set()
        s.add(edges[0][0])
        s.add(edges[0][1])
        l = [s]
        for i in range(1, len(edges)):
            first = self.find(edges[i][0], l)
            second = self.find(edges[i][1], l)
            if first == -1 and second == -1:
                l.append(set([edges[i][0], edges[i][1]]))
            elif first == second:
                return False
            elif first != -1 and second != -1:
                if first > second:
                    temp = l[first]
                    del l[first]
                    l[second] = l[second] | temp
                else:
                    temp = l[second]
                    del l[second]
                    l[first] = l[first] | temp
            else:
                if first != -1:
                    l[first].add(edges[i][1])
                else:
                    l[second].add(edges[i][0])
            
        if len(l) == 1:
            return True
        else:
            return False
            
    def find(self, e, l):
        for i in range(len(l)):
            if e in l[i]:
                return i
        return -1


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值