zoukankan      html  css  js  c++  java
  • [LeetCode] 261. 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.

    Example 1:

    Input: n = 5, and edges = [[0,1], [0,2], [0,3], [1,4]]
    Output: true

    Example 2:

    Input: n = 5, and edges = [[0,1], [1,2], [2,3], [1,3], [1,4]]
    Output: false

    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.

    以图判树。

    给定从 0 到 n-1 标号的 n 个结点,和一个无向边列表(每条边以结点对来表示),请编写一个函数用来判断这些边是否能够形成一个合法有效的树结构。

    注意:你可以假定边列表 edges 中不会出现重复的边。由于所有的边是无向边,边 [0,1] 和边 [1,0] 是相同的,因此不会同时出现在边列表 edges 中。

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/graph-valid-tree
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    这道题属于图和树的综合题。给的input是节点的个数n和一些边edges,请你判断能否组成一棵树。有一个概念需要复习,树和图的区别在于图是可以有环 (cycle) 的,树不能有环;同时图的节点有可能不会连在一片,但是树的所有节点必定都是相连成一片的。对于这道题,有一些corner case需要特判,如果只有一个节点的话,那么就一定没有edges;因为题设说了不会给额外的边,所以如果边的数量 != 节点数量 - 1的话,一定不是树。

    照着这个思路,我还是提供三种做法,BFS, DFS和Union Find。三种做法的时间空间复杂度都一样,union find在运行时间上可以通过路径压缩变得更快。

    BFS

    时间O(V * E)

    空间O(n)

    Java实现

     1 class Solution {
     2     public boolean validTree(int n, int[][] edges) {
     3         // create graph
     4         List<List<Integer>> graph = new ArrayList<>();
     5         for (int i = 0; i < n; i++) {
     6             graph.add(new ArrayList<>());
     7         }
     8         for (int i = 0; i < edges.length; i++) {
     9             graph.get(edges[i][0]).add(edges[i][1]);
    10             graph.get(edges[i][1]).add(edges[i][0]);
    11         }
    12 
    13         boolean[] visited = new boolean[n];
    14         Queue<Integer> queue = new LinkedList<>();
    15         queue.offer(0);
    16         while (!queue.isEmpty()) {
    17             int cur = queue.poll();
    18             if (visited[cur] == true) {
    19                 return false;
    20             }
    21             visited[cur] = true;
    22             for (int nei : graph.get(cur)) {
    23                 if (!visited[nei]) {
    24                     queue.offer(nei);
    25                 }
    26             }
    27         }
    28 
    29         for (int i = 0; i < n; i++) {
    30             if (visited[i] == false) {
    31                 return false;
    32             }
    33         }
    34         return true;
    35     }
    36 }

    DFS

    时间O(V * E)

    空间O(n)

    Java实现

     1 class Solution {
     2     public boolean validTree(int n, int[][] edges) {
     3         // create graph
     4         List<List<Integer>> g = new ArrayList<>();
     5         for (int i = 0; i < n; i++) {
     6             g.add(new ArrayList<>());
     7         }
     8         for (int[] e : edges) {
     9             g.get(e[0]).add(e[1]);
    10             g.get(e[1]).add(e[0]);
    11         }
    12 
    13         HashSet<Integer> visited = new HashSet<>();
    14         visited.add(0);
    15         boolean res = helper(g, visited, 0, -1);
    16         if (res == false) {
    17             return false;
    18         }
    19         return visited.size() == n ? true : false;
    20     }
    21 
    22     private boolean helper(List<List<Integer>> g, HashSet<Integer> visited, int cur, int parent) {
    23         List<Integer> neighbors = g.get(cur);
    24         for (int nei : neighbors) {
    25             if (nei == parent) {
    26                 continue;
    27             }
    28             // cycle
    29             if (visited.contains(nei)) {
    30                 return false;
    31             }
    32             visited.add(nei);
    33             boolean res = helper(g, visited, nei, cur);
    34             if (res == false) {
    35                 return false;
    36             }
    37         }
    38         return true;
    39     }
    40 }

    Union Find

    时间O(V * E)

    空间O(n)

    Java实现

     1 class Solution {
     2     public boolean validTree(int n, int[][] edges) {
     3         // corner case
     4         if (n == 1 && edges.length == 0) {
     5             return true;
     6         }
     7         if (n < 1 || edges == null || edges.length != n - 1) {
     8             return false;
     9         }
    10 
    11         // normal case
    12         int[] roots = new int[n];
    13         for (int i = 0; i < n; i++) {
    14             roots[i] = -1;
    15         }
    16 
    17         for (int[] pair : edges) {
    18             int x = find(roots, pair[0]);
    19             int y = find(roots, pair[1]);
    20             if (x == y) {
    21                 return false;
    22             }
    23             roots[x] = y;
    24         }
    25         return true;
    26     }
    27 
    28     private int find(int[] roots, int i) {
    29         while (roots[i] != -1) {
    30             i = roots[i];
    31         }
    32         return i;
    33     }
    34 }

    相关题目

    261. Graph Valid Tree

    323. Number of Connected Components in an Undirected Graph

    547. Friend Circles

    LeetCode 题目总结

  • 相关阅读:
    iOS10---新特性以及适配点
    linux下,MySQL默认的数据文档存储目录为/var/lib/mysql。
    Linux安装JDK完整步骤
    ajax获取json数据为undefined--原因解析
    怎样用jQuery拿到select中被选中的option的值
    一个Filter需要配置多个url-pattern
    Jquery+Ajax实现Select动态添加数据
    tomcat启动报错:Address already in use: JVM_Bind
    Gson 是google解析Json的一个开源框架,同类的框架fastJson,JackJson
    Java中文乱码解决方案
  • 原文地址:https://www.cnblogs.com/cnoodle/p/14199807.html
Copyright © 2011-2022 走看看