1. 程式人生 > >leetcode 261-Graph Valid Tree(medium)(BFS, DFS, Union find)

leetcode 261-Graph Valid Tree(medium)(BFS, DFS, Union find)

poll != bfs node 如果 為什麽 rec connect off

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.

這道題主要就是判斷1.是否有環路 2. 是否是連通圖

可以用DFS, BFS 和 Union find,union find最合適。

對於DFS和BFS,首先都是建立adjacent list,把edges連接的所有情況加入鄰接鏈表,註意需要對稱加入,對於[a,b],要對a加入b,對b加入a。都可以用visited來記錄是否遍歷過。

1. BFS

bfs基本都是用queue實現,首先加入第一個點,每次poll出一個點,對其鄰接鏈表遍歷,入隊,註意要將該點從其遍歷到的鄰接鏈表的點的鄰接鏈表中刪去,保證一條邊不會來回走兩次(為什麽前面要對稱加入而這裏又要刪去一邊,因為不知道點之間聯通的情況是怎麽樣的,在進行遍歷的時候可能是從a->b的方向也可能相反,如果只加一個,在連通圖遍歷的時候本來連著的邊會斷掉)。用count記錄連入連通圖的點的個數,最後和n比。

再次提醒,對於list之類get到的點,都是object,不是int,在賦值給int時要(int),在用remove時,註意remove掉的是object,不能是int,remove(int index),remove(object ob),這兩種要區分開,這裏是要remove掉這個對象,所以要加(Integer)。

class Solution {
    public boolean validTree(int n, int[][] edges) {
        if(n==0) return false;
        List[] list=new List[n];
        for(int i=0;i<n;i++){
            list[i]=new ArrayList<Integer>();
        }
        for(int[] pair:edges){
            list[pair[0]].add(pair[1]);
            list[pair[
1]].add(pair[0]); } Queue<Integer> queue=new LinkedList<>(); queue.offer(0); boolean[] visited=new boolean[n]; int count=1; while(!queue.isEmpty()){ int a=queue.poll(); if(visited[a]) return false; visited[a]=true; for(int i=0;i<list[a].size();i++){ int m=(int)list[a].get(i);//註意要轉int queue.offer(m); count++; list[m].remove((Integer)a);//註意要加(Integer),要不然是被認為是index,刪除 } } return count==n; } }

2.DFS

dfs中需要記錄pre,來避免a->b->a這樣的遍歷,從而被當成是環路。

class Solution {
    public boolean validTree(int n, int[][] edges) {
        if(n==0) return false;
        List[] list=new List[n];
        for(int i=0;i<n;i++){
            list[i]=new ArrayList<Integer>();
        }
        for(int[] pair:edges){
            list[pair[0]].add(pair[1]);
            list[pair[1]].add(pair[0]);
        }
        boolean[] visited=new boolean[n];
        if(dfs(list, visited, 0,-1)) return false;
        for(int i=0;i<n;i++){
            if(!visited[i]) return false;
        }
        return true;
    }
    public boolean dfs(List[] list, boolean[] visited, int id, int pre){
        if(visited[id]) return true;
        visited[id]=true;
        for(int i=0;i<list[id].size();i++){
            if(pre==(int)list[id].get(i)) continue;
            if(dfs(list, visited, (int)list[id].get(i), id)) return true;
        }
        return false;
    }
}

3. Union Find

用count記錄連通圖的個數,每並一次說明少一個分裂塊,如果最後變為1,說明全部連通。

class Solution {
    public boolean validTree(int n, int[][] edges) {
        int[] connect=new int[n];
        if(edges.length!=n-1) return false;
        for(int i=0;i<n;i++){
            connect[i]=i;
        }
        int count=n;
        for(int i=0;i<edges.length;i++){
            int a=findroot(connect,edges[i][0]);
            int b=findroot(connect,edges[i][1]);
            if(a==b) return false;
            count--;
            connect[b]=a;
        }
        return count==1;
    }
    public int findroot(int[] connect, int id){
        while(connect[id]!=id) id=connect[id];
        return id;
    }
}

leetcode 261-Graph Valid Tree(medium)(BFS, DFS, Union find)