[Leetcode] 261. Graph Valid Tree

[Leetcode] 261. Graph Valid Tree_第1张图片

这题本质并不复杂, 只是操作起来略烦和需要小心
一个图是否为树,判断条件有二:1.是否存在环。2.是否0 ~ n - 1这n个点都被走完了,也就是木有orphan nodes
所以整个流程基本就是:根据输入建图,然后遍历图找环,无环而且走过的节点数为n即是树。

构图的方式很多种,可以自己开一个class。如果懒得这么做,一般用哈希表也可以HashMap(儿子节点群)>表示。题目也给你提示了,输入是根据无向图的结构进行输入的,也就是一条边等同于有向图的两条边,ex. [0, 1] 等同于 0 -> 1, 1 -> 0。同样的,也因为如此,遍历树的时候,判断是否为环的时候要忽略长度为1的环。也就是0 -> 1 -> 0这样的环可以忽略。

根据上述描述,可以得到代码如下:

    public boolean validTree(int n, int[][] edges) {
        HashMap> directed = new HashMap<>();
        for (int[] edge : edges) {
            if (!directed.containsKey(edge[0])) directed.put(edge[0], new HashSet());
            if (!directed.containsKey(edge[1])) directed.put(edge[1], new HashSet());
            
            directed.get(edge[0]).add(edge[1]);
            directed.get(edge[1]).add(edge[0]);
        }
        
        HashSet visited = new HashSet<>();
        if (!_hasNoCycle(directed, visited, -1, 0)) return false;
        
        return visited.size() == n;
    }
    
    private boolean _hasNoCycle(HashMap> directed, HashSet visited, int parent, int current) {
        if (visited.contains(current)) {
            return false;
        } else {
            visited.add(current);
            HashSet children = directed.get(current);
            if (children == null) return true;

            for (int child : children) {
                if (child == parent) continue;

                if (!_hasNoCycle(directed, visited, current, child)) {
                    return false;
                }
            }
            
            return true;
        }
    }

其中if(children == null) return true主要针对的是n = 1的时候只有一个0节点的edge case,这个其实也是一颗合法的树。

你可能感兴趣的:(Leetcode)