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

    For example:

    Given n = 5 and edges = [[0, 1], [0, 2], [0, 3], [1, 4]], return true.

    Given n = 5 and edges = [[0, 1], [1, 2], [2, 3], [1, 3], [1, 4]], return false.

    Hint:

    1. Given n = 5 and edges = [[0, 1], [1, 2], [3, 4]], what should your return? Is this case a valid tree? Show More Hint 

    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.

    链接: http://leetcode.com/problems/graph-valid-tree/

    5/13/2017

    算法班,抄答案

    8ms, 39%

    被hashCode跑偏了,没有想起来怎么做这道题。

    最后用顶点做hashset比用边要好。因为用边不容易检测到环。

    http://www.jiuzhang.com/solutions/graph-valid-tree/

     1 public class Solution {
     2 
     3     public boolean validTree(int n, int[][] edges) {
     4         // make sure E == V - 1
     5         if (edges == null || edges.length != n - 1) {
     6             return false;
     7         }
     8         Map<Integer, Set<Integer>> graph = initializeGraph(n, edges);
     9         Queue<Integer> queue = new LinkedList<Integer>();
    10         Set<Integer> set = new HashSet<Integer>();
    11         queue.offer(0);
    12         set.add(0);
    13         
    14         while (!queue.isEmpty()) {
    15             Integer v = queue.poll();
    16             for (Integer neighbor: graph.get(v)) {
    17                 if (!set.contains(neighbor)) {
    18                     queue.offer(neighbor);
    19                     set.add(neighbor);
    20                 }
    21             }
    22         }
    23         return set.size() == n;
    24     }
    25     private Map<Integer, Set<Integer>> initializeGraph(int n, int[][] edges) {
    26         Map<Integer, Set<Integer>> map = new HashMap<>();
    27         
    28         for (int i = 0; i < n; i++) {
    29             map.put(i, new HashSet<Integer>());
    30         }
    31         for (int i = 0; i < edges.length; i++) {
    32             int e = edges[i][0];
    33             int o = edges[i][1];
    34             map.get(e).add(o);
    35             map.get(o).add(e);
    36         }
    37         return map;
    38     }
    39 }

    顺便实现了一次hashCode

     1     class Edge {
     2         final int either, other;
     3         Edge(int[] edge) {
     4             if (edge[0] < edge[1]) {
     5                 this.either = edge[0];
     6                 this.other = edge[1];                
     7             } else {
     8                 this.other = edge[0];
     9                 this.either = edge[1];
    10             }
    11         }
    12         @Override
    13         public boolean equals(Object obj) {
    14             if (obj == null) return false;
    15             if (!(obj instanceof Edge)) return false;
    16             Edge o = (Edge) obj;
    17             if (o.either == this.either && o.other == this.other) {
    18                 // because we already ordered the two V, no need to check other direction
    19                 return true;
    20             }
    21             return false;
    22         }
    23         @Override
    24         public int hashCode() {
    25             int hash = 7;
    26             hash = 71 * hash + this.either;
    27             hash = 71 * hash + this.other;
    28             return hash;        
    29         }
    30     }

    还有union-find的方法。

    1ms, 73%

     1 public class Solution {
     2     class WeightedUnionFind {
     3         int[] parent;
     4         int[] size;
     5         
     6         WeightedUnionFind(int n) {
     7             parent = new int[n];
     8             size = new int[n];
     9             for (int i = 0; i < n; i++) {
    10                 parent[i] = i;
    11                 size[i] = 1;
    12             }
    13         }
    14         int find(int p) {
    15             while (parent[p] != p) {
    16                 parent[p] = parent[parent[p]]; //1-pass path compression, every other node in the path points to its grandfather
    17                 p = parent[p];
    18             }
    19             return p;
    20         }
    21         void union(int p, int q) {
    22             int rootP = find(p);
    23             int rootQ = find(q);
    24             // check if already connected or not
    25             if (rootP == rootQ) {
    26                 return;
    27             }
    28             if (size[rootP] < size[rootQ]) {
    29                 parent[rootP] = rootQ;
    30                 size[rootQ] += size[rootQ];
    31             } else {
    32                 parent[rootQ] = rootP;
    33                 size[rootP] += size[rootQ];
    34             }
    35         }
    36         boolean connected(int p, int q) {
    37             return find(p) == find(q);
    38         }
    39     }
    40     public boolean validTree(int n, int[][] edges) {
    41         if (edges == null || edges.length != n - 1) return false;
    42         WeightedUnionFind uf = new WeightedUnionFind(n);
    43         for (int i = 0; i < edges.length; i++) {
    44             int p = edges[i][0];
    45             int q = edges[i][1];
    46             if (uf.connected(p, q)) return false;
    47             uf.union(edges[i][0], edges[i][1]);
    48         }
    49         return true;
    50     }
    51 }

    更多讨论:

    https://discuss.leetcode.com/category/330/graph-valid-tree

  • 相关阅读:
    HTML DOM教程 14HTML DOM Document 对象
    HTML DOM教程 19HTML DOM Button 对象
    HTML DOM教程 22HTML DOM Form 对象
    HTML DOM教程 16HTML DOM Area 对象
    ubuntu 11.04 问题 小结
    VC6.0的 错误解决办法 小结
    boot.img的解包与打包
    shell里 截取字符串
    从零 使用vc
    Imagemagick 对图片 大小 和 格式的 调整
  • 原文地址:https://www.cnblogs.com/panini/p/6852084.html
Copyright © 2011-2022 走看看