[LeetCode] 128. Longest Consecutive Sequence

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.

Thought process:
Iterate through the array, use a hashset to store all the numbers. Iterate through the array again, when I see a number, I check if number-- is in the set until it's not. If it's in the set, remove it from the set. Check number++ in the same fashion. This gives me O(n) time complexity because every number is iterated at most once.

Solution 1 (Set):
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class Solution {
    public int longestConsecutive(int[] nums) {
        Set<Integer> set = new HashSet<>();
        for (int num : nums) {
            set.add(num);
        }
        
        int longest = 0;
        for (int num : nums) {
            int currentLongest = 0;
            int temp = num;
            while (set.contains(num)) {
                currentLongest++;
                set.remove(num);
                num--;
            }
            num = temp + 1;
            while (set.contains(num)) {
                currentLongest++;
                set.remove(num);
                num++;
            }
            longest = Math.max(longest, currentLongest);
        }
        
        return longest;
    }
}

The question can also be solved using union find. In order to find a number's neighbors quickly, we need to use a hash map as the union find data structure.

Solution 2 (Union find):
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
class Solution {
    private int longest = 1;
    private Map<Integer, Integer> parent = new HashMap<>();
    private Map<Integer, Integer> size = new HashMap<>();
    
    public int longestConsecutive(int[] nums) {
        if (nums.length == 0) {
            return 0;
        }
        
        for (int num : nums) {
            if (parent.containsKey(num)) {
                continue;
            }
            
            parent.put(num, num);
            size.put(num, 1);
            if (parent.containsKey(num - 1)) {
                union(num, num - 1);
            }
            if (parent.containsKey(num + 1)) {
                union(num, num + 1);
            }
        }
        return longest;
    }
    
    private void union(int a, int b) {
        int p1 = find(a);
        int p2 = find(b);
        int size1 = size.get(p1);
        int size2 = size.get(p2);
        
        if (size1 < size2) {
            parent.put(p1, p2);
            size.put(p2, size1 + size2);
        } else {
            parent.put(p2, p1);
            size.put(p1, size1 + size2);
        }
        longest = Math.max(longest, size1 + size2);
    }
    
    private int find(int i) {
        while (parent.get(i) != i) {
            parent.put(i, find(parent.get(i)));
            i = parent.get(i);
        }
        return i;
    }
}

Time complexity: O(n).

Comments

Popular posts from this blog

[LeetCode] 714. Best Time to Buy and Sell Stock with Transaction Fee

[LeetCode] 269. Alien Dictionary

[LeetCode] 631. Design Excel Sum Formula