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 }