261. Graph Valid Tree

Question

You have a graph of n nodes labeled from 0 to n - 1. You are given an integer n and a list of edges where edges[i] = [ai, bi] indicates that there is an undirected edge between nodes ai and bi in the graph.

Return true if the edges of the given graph make up a valid tree, and false otherwise.

Algorithm

We are asking to find if the given graph is a tree. A tree is a connected acyclic graph.

So we could know our union find is to do this. To check if there is a cycle. When we do the union operation, we try to put vertexes of an edge into same set, then we find that they are already in a set. This indicates that there is a cycle.

And we need to check the graph is connected. First I traverse all the nodes in a double loop to see if they are connected. However, we only need to check if the edge number is node number minus one.

Code

class Solution {
    int[] parents;
    int[] size;
    public boolean validTree(int n, int[][] edges) {
        if (edges.length != n - 1) {
            return false;
        }
        parents = new int[n];
        size = new int[n];
        for (int i = 0; i < n; i++) {
            parents[i] = i;
            size[i] = 1;
        }
        
        for (int[] edge : edges) {
            if (union(edge[0], edge[1], n) == false) {
                return false;
            }
        }
        
        return true;
    }
    
    private boolean union(int x, int y, int n) {
        int xRoot = find(x);
        int yRoot = find(y);
        if (xRoot == yRoot) {
            return false;
        }
        if (size[xRoot] > size[yRoot]) {
            parents[yRoot] = xRoot;
            size[xRoot] += size[yRoot];
        } else {
            parents[xRoot] = yRoot;
            size[yRoot] += size[xRoot];
        }
        return true;
    }
    
    private int find(int x) {
        if (x != parents[x]) {
            parents[x] = find(parents[x]);
        }
        return parents[x];
    }
}