Leetcode 128. Longest Consecutive Sequence (union find)

Given an unsorted array of integers, find the length of the longest consecutive elements sequence.

Your algorithm should run in O(n) complexity.

Example:

Input: [100, 4, 200, 1, 3, 2]
Output: 4
Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]. Therefore its length is 4.

tag : union find

create the array first and then union the consecutive number (3,4)  (4,5) -- > have the same root

e.g: 100   4   200  1   3  2

       100  4   200   1   3  2

My method: weighted union find with hashmap;

Solution 1

class Solution {
    //union find
     class QuickUnion {//with array
    HashMap<Integer, Integer> map = new HashMap<>(); // id, parent
    HashMap<Integer, Integer> sz = new HashMap<>(); // id size
    int count;//how many components
    QuickUnion(int[] nums){
        count = 1;
        for(int i = 0; i<nums.length;i++) {
            map.put(nums[i],nums[i]);
            sz.put(nums[i],1);
        }
    }
    Integer root(int p){
        if(!map.containsKey(p)) return null; // there is no such id
        
        while(p != map.get(p)){
            int temp = map.get(map.get(p));//with path compression , set parent -> grandparent, map.get(i): i 's parent
            map.put(p, temp);
            p = map.get(p);
        }
        
        /*while(id[p] != p){//find the root when to stop
            id[p] = id[id[p]];
            p = id[p];
        }*/
        return p;
    }
    boolean find(int p, int q){
        return root(p)==root(q);
    }
    void union(int p, int q){
        //get root
        Integer pid = root(p);
        Integer qid = root(q);
        System.out.println(qid);
        if(pid == null || qid == null) return; // check the null
        //if(pid == qid) return; // check the integer,. heck if in the same set
        if(pid.equals(qid)) return; 
        if(sz.get(pid) > sz.get(qid)){
            map.put(qid, pid);
            sz.put(pid, sz.get(pid)+sz.get(qid));
            if(sz.get(pid)>count) count = sz.get(pid);
        }else{
            map.put(pid, qid);
            sz.put(qid, sz.get(pid)+sz.get(qid));
            if(sz.get(qid)>count) count = sz.get(qid);
        }
        
    }
    }
    public int longestConsecutive(int[] nums) {
        //create a union find 
        //union the elemnt  4 (3,5) -> 3,4,5
        if(nums.length == 0) return 0;
        QuickUnion qu = new QuickUnion(nums);
        for(int i = 0; i<nums.length; i++){
            System.out.println("num of i"+i+" ");
            if(nums[i] != Integer.MIN_VALUE) qu.union(nums[i],nums[i]-1);//check the boundary
            if(nums[i] != Integer.MAX_VALUE) qu.union(nums[i],nums[i]+1);//[2147483646,-2147483647,0,2,2147483644,-2147483645,2147483645]
            System.out.println(qu.count+" ");
        }
        return qu.count;
    }
}

Solution: hashset

remove and contains in ahshset 

flow: remove the element : visited that element

class Solution {
    public int longestConsecutive(int[] nums) {
        if(nums.length==0) return 0;
        //use hashset
        HashSet<Integer> set = new HashSet<>();//non duplicate element
        for(int num : nums){
            set.add(num);
        }
        
        int max = 1;
        for(int num : nums){
            int len = 0;
            int left = 1, right = 1;
            if(!set.contains(num)) continue;
            
            while(set.contains(num-left)){
                set.remove(num-left); left++; len++;
            }
            while(set.contains(num+right)){
                set.remove(num+right); right++; len++;
            }
                 len++;
            set.remove(num);
            max = Math.max(len, max);
            
        }
        return max;
    }
}

quick find and quick union and weightedunion find 

public class QuickFind{
    private int[] id; // set all root of current id
    
    public QuickFind(int N){
        id = new int[N];
        for (int i = 0; i < N; i++)
            id[i] = i;
    }
    //Check if p and q have the same id.
    boolean find(int p, int q){
        return id[p]==id[q]; 
    }
    //union pq
    void unite(int p, int q){
        int pid = id[p];//change pid to q
        for(int i = 0; i <id.length; i++){
            if(id[i] == pid) id[i] = id[q];
        }
    }

}

public class QuickUnion{
    private int[] id; //represent the parent instead of root
    
    public QuickUnion(int N){
        id = new int[N];
        for (int i = 0; i < N; i++)
            id[i] = i;
    }
    //Check if p and q have the same id.
    boolean find(int p, int q){
        return root(p)==root(q); 
    }
    //get the root
    int root(int i){
        while(i != id[i]) i = id[i];//id[i] parent i: children
        return i;
    }
    //union p q
    void unite(int p, int q){
        //find root first
        int i = root(p);
        int j = root(q);
        id[i] = j;
    }
}

//avoid the tall trees , keep track ther size of each component
public class WeightedQuickUnion{
    private int[] id; //represent the parent instead of root
    private int[] sz;
    int count;
    public WeightedQuickUnion(int N){
        count = N;
        id = new int[N];
        sz = new int[N];
        for (int i = 0; i < N; i++){
            id[i] = i;
            sz[i] = 1;
        }
            
    }
    //Check if p and q have the same id.
    boolean find(int p, int q){
        return root(p)==root(q); 
    }
    //get the root
    int root(int i){
        while(i != id[i]) {
            // path compression
            id[i] = id[id[i]];
            i = id[i];//id[i] parent i: children
        }
        return i;
    }
    //union p q
    void unite(int p, int q){
        //find root first
        int i = root(p);
        int j = root(q);
        if(sz[i]<sz[j]){ //samller tree to larger tree
            id[i] = j; sz[j]+=sz[i];
        }else {
            id[j] = i; sz[i]+=sz[j];
        }
        count--;
    }
}

猜你喜欢

转载自www.cnblogs.com/stiles/p/leetcode128.html