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

For example,
Given [100, 4, 200, 1, 3, 2],
The longest consecutive elements sequence is [1, 2, 3, 4]. Return its length: 4.

Your algorithm should run in O(n) complexity.

Best Solution: only scan one direction, 

 If the number x is the start of a streak (i.e., x-1 is not in the set), then test y = x+1, x+2, x+3, ... and stop at the first number y not in the set. The length of the streak is then simply y-x and we update our global best with that. Since we check each streak only once, this is overall O(n). 

 1 public class Solution {
 2     /**
 3      * @param nums: A list of integers
 4      * @return an integer
 5      */
 6     public int longestConsecutive(int[] num) {
 7         // write you code here
 8         HashSet<Integer> set = new HashSet<Integer>();
 9         for (int elem : num) {
10             set.add(elem);
11         }
12         int longestLen = 0;
13         for (int n : set) {
14             if (!set.contains(n-1)) {
15                 int len = 0;
16                 while (set.contains(n)) {
17                     len++;
18                     n++;
19                 }
20                 longestLen = Math.max(longestLen, len);
21             }
22         }
23         return longestLen;
24     }
25 }

 

Union Find (optional), just to know that there's this solution

 1 class Solution {
 2     public int longestConsecutive(int[] nums) {
 3         HashMap<Integer, Integer> map = new HashMap<>();
 4         unionFind uf = new unionFind(nums.length);
 5         for (int i = 0; i < nums.length; i ++) {
 6             uf.fathers[i] = i;
 7             uf.count ++;
 8             if (map.containsKey(nums[i])) continue;
 9             map.put(nums[i], i);
10             if (map.containsKey(nums[i] - 1)) {
11                 uf.union(i, map.get(nums[i] - 1));
12             }
13             if (map.containsKey(nums[i] + 1)) {
14                 uf.union(i, map.get(nums[i] + 1));
15             }
16         }
17         return uf.maxUnion();
18     }
19     
20     public class unionFind {
21         int[] fathers;
22         int count;
23         
24         public unionFind(int num) {
25             this.fathers = new int[num];
26             Arrays.fill(this.fathers, -1);
27             this.count = 0;
28         }
29         
30         public void union(int i, int j) {
31             if (isConnected(i, j)) return;
32             int iRoot = find(i);
33             int jRoot = find(j);
34             fathers[iRoot] = jRoot;
35             this.count --;
36         }
37         
38         public int find(int i) {
39             while (fathers[i] != i) {
40                 i = fathers[i];
41             }
42             return i;
43         }
44         
45         public boolean isConnected(int i, int j) {
46             return find(i) == find(j);
47         }
48         
49          // returns the maxium size of union
50         public int maxUnion(){ // O(n)
51             int[] count = new int[fathers.length];
52             int max = 0;
53             for(int i=0; i<fathers.length; i++){
54                 count[find(i)] ++;
55                 max = Math.max(max, count[find(i)]);
56             }
57             return max;
58         }
59     }
60 }