261. Graph Valid Tree


June-23-2019

先用UF做了一下,这个不容易想到。valid tree说明
UF最终只有一个group
每次加的2个node都不能发现它已经在树里了。
比如[1,2][3,4]第一个条件不满足
[1,2][2,3][1,3]第二个条件不满足

然后做就行了。其实用n + 1 == edges.length就足够判断第一个条件了。。

find的时候,先压缩树,父指到爷;然后再find第二次,都指向最终root(这2个其实冲突了,相当于第二次指向root只指了其中的一半)

UF的用size来平衡树,永远小的往大的上面连。然而其实有上面的过程,balance不是很有必要,毕竟find()的时间按理说是1.锻炼下还是写了,否则代码能简单很多

class Solution {
    public class UF {
        Map<Integer, Integer> parent;
        Map<Integer, Integer> height;
        int group = 0;
        
        public UF(int n) {
            parent = new HashMap<>();
            height = new HashMap<>();
            for (int i = 0; i < n; i ++) {
                parent.put(i, i);
                height.put(i, 1);
            }
            group = n;
        }
        
        public Integer find(Integer i) {
            if (i == null || !parent.containsKey(i)) return null;
            
            Integer root = i;
            while (!root.equals(parent.get(root))) {
                parent.put(root, parent.get(parent.get(root)));
                root = parent.get(root);
            }
            
            while (!i.equals(root)) {
                Integer temp = parent.get(i);
                parent.put(i, root);
                i = temp;
            }
            return root;
        }
        
        public void union(Integer a, Integer b) {
            Integer rootA = find(a);
            Integer rootB = find(b);
            if (rootA == null || rootB == null) return;
            if (rootA.equals(rootB)) return;
            
            Integer heightA = height.get(rootA);
            Integer heightB = height.get(rootB);
            
            if (heightA > heightB) {
                parent.put(rootB, rootA);
                height.put(heightA, heightA + heightB);
            } else {
                parent.put(rootA, rootB);
                height.put(heightB, heightA + heightB);
            }
            group --;
        }
    }
    
    
    public boolean validTree(int n, int[][] edges) {
        UF uf = new UF(n);
        
        for (int[] edge : edges) {
            Integer rootA = uf.find(edge[0]);
            Integer rootB = uf.find(edge[1]);
            if (rootA.equals(rootB)) {
                return false;
            } else {
                uf.union(rootA, rootB);
            }
        }
        return uf.group == 1;
    }
}

然后什么都不考虑的简单版UF

class Solution {    
        public int find(int i, int[] nums) {
            while (i != nums[i]) {
                i = nums[i];
            }
            return i;
        }
        
        public void union(Integer a, Integer b, int[] nums) {
            nums[a] = nums[b];  
        }
     
    public boolean validTree(int n, int[][] edges) {
        
        int[] node = new int[n];
        for (int i = 0; i < n; i ++) {
            node[i] = i;
        }
        for (int[] edge : edges) {
            int a = find(edge[0], node);
            int b = find(edge[1], node);

            if (a == b) {
                return false;
            } else {
                union(a, b, node);
            }
        }
        return edges.length == n - 1;
    }
}
posted @ 2016-12-02 12:51  哇呀呀..生气啦~  阅读(222)  评论(0编辑  收藏  举报