[leetcode] 261. Graph Valid Tree

valid tree: = 无向图+无环+只一个连通分量

Solution 1 : BFS

思路参考:
算法1:
我们知道对于环 1-2-3-4-1,每个节点的度都是2,基于此我们有如下算法(这是类似于有向图的拓扑排序):

求出图中所有顶点的度
删除图中所有度 <=1 的顶点以及与该顶点相关的边,把与这些边相关的顶点的度减一
如果还有度<=1的顶点重复步骤2
最后如果还存在未被删除的顶点,则表示有环;否则没有环
时间复杂度为O(E+V),其中E、V分别为图中边和顶点的数目。

class Solution {
    public boolean validTree(int n, int[][] edges) {
        // 判断只有一个连通分量
        if(n-1 > edges.length) return false;
        
        //用bfs判断无cycle
        HashMap indegree = new HashMap<>();
        HashMap> graph = new HashMap<>();
        
        //初始化 indegree
        for(int i = 0 ; i < n;i++){
            graph.put(i,new ArrayList<>());
            indegree.put(i,0);
        }
        
        for(int i = 0 ; i < edges.length;i++){
            int[] edge = edges[i];
            indegree.put(edge[1],indegree.getOrDefault(edge[1],0) + 1);
            indegree.put(edge[0],indegree.getOrDefault(edge[0],0) + 1);
            graph.get(edge[0]).add(edge[1]);
            graph.get(edge[1]).add(edge[0]);
            
        }
        
        Queue queue = new LinkedList<>();
        int validCount = 0;
        for(int i = 0; i < indegree.size();i++){
            if(indegree.get(i) <= 1){
                queue.offer(i);
            }
        }
        
        while(!queue.isEmpty()){
            int node = queue.poll();
            validCount++;
            System.out.println(node);
            for(int neigh:graph.get(node)){
                indegree.put(neigh, indegree.get(neigh) - 1);
                if(indegree.get(neigh) == 1){
                    queue.offer(neigh);
                }
            }
        }
        
        if(validCount == n){
            return true;
        }
        
        return false;
        
    }
}

Solution 2: Union find

class Solution {
    public boolean validTree(int n, int[][] edges) {
        // 判断只有一个连通分量
        if(n-1 > edges.length) return false;
        
        int[] nodes = new int[n];
        Arrays.fill(nodes,-1);
        
        for(int[] edge: edges){
            int x = find(nodes, edge[0]);
            int y = find(nodes, edge[1]);
            
            if(x == y) return false;
            
            nodes[x] = y;
            
        }
        
        return true;
    }
    
    public int find(int[] nodes, int i){
        if(nodes[i] == -1) return i;
        return find(nodes, nodes[i]);
    }
}

Solution 3: DFS

重点是这个

if(visited[v] && parent != v){
                return true;
            }
            
if(!visited[v] && hasCycle(graph, v,visited,u)){
    return true;
}
class Solution {
    public boolean validTree(int n, int[][] edges) {
        
        HashMap> graph = new HashMap<>();
        for(int i = 0 ; i < n ;i++){
            graph.put(i, new ArrayList<>());
        }
        
        for(int i = 0 ; i < edges.length;i++){
            int[] edge = edges[i];
            graph.get(edge[0]).add(edge[1]);
            graph.get(edge[1]).add(edge[0]);
        }
        
        boolean[] visited = new boolean[n];
        
        if(hasCycle(graph,0,visited,-1)){
            return false;
        }
        
        // 判断只有一个连通分量
        for (int i = 0; i < n; i++) {
            if (!visited[i]) 
                return false;
        }
        
        
        return true;
        
        
       
    }
    
    public boolean hasCycle(HashMap> graph, int u, boolean[] visited,int parent){
        visited[u] = true;
        for(int i = 0 ; i < graph.get(u).size();i++){
            int v = graph.get(u).get(i);
            
            if(visited[v] && parent != v){
                return true;
            }
            
            if(!visited[v] && hasCycle(graph, v,visited,u)){
                return true;
            }
        }
        
        return false;
    }
    
    
}

你可能感兴趣的:(leetcode)