LeetCode – Longest Consecutive Sequence (Java)

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 should be [1, 2, 3, 4]. Its length is 4.

Your algorithm should run in O(n) complexity.

Java Solution 1

Because it requires O(n) complexity, we can not solve the problem by sorting the array first. Sorting takes at least O(nlogn) time.

We can use a HashSet to add and remove elements. HashSet is implemented by using a hash table. Elements are not ordered. The add, remove and contains methods have constant time complexity O(1).

public static int longestConsecutive(int[] num) {
	// if array is empty, return 0
	if (num.length == 0) {
		return 0;
	}
 
	Set<Integer> set = new HashSet<Integer>();
	int max = 1;
 
	for (int e : num)
		set.add(e);
 
	for (int e : num) {
		int left = e - 1;
		int right = e + 1;
		int count = 1;
 
		while (set.contains(left)) {
			count++;
			set.remove(left);
			left--;
		}
 
		while (set.contains(right)) {
			count++;
			set.remove(right);
			right++;
		}
 
		max = Math.max(count, max);
	}
 
	return max;
}

Java Solution 2

We can also project the arrays to a new array with length to be the largest element in the array. Then iterate over the array and get the longest consecutive sequence. If the largest number is too large, then the time would be bad. This is just another thought.

Category >> Algorithms  
If you want someone to read your code, please put the code inside <pre><code> and </code></pre> tags. For example:
<pre><code> 
String foo = "bar";
</code></pre>

  1. Wellwisher on 2014-4-15
  2. violethaze on 2014-5-14

    when n = m, the complexity will be O(n^2)

  3. Dun Liu on 2014-5-18

    if num.length==0, it will return max as 1. Which is wrong

  4. cj on 2014-10-18

    wrong answer dude: think about [1 2 4 5 3]

  5. Mo on 2014-10-22

    Just put a check in the beginning before int max=1.

    if(num.length == 0){
    return 0;
    }

  6. ryanlr on 2014-10-22

    Thanks! The code is updated.

  7. ryanlr on 2014-10-22

    I just tested the code using {1,2,4,5,3}, the result is 5, which is correct.

  8. ryanlr on 2014-10-22

    That is correct. Thanks for pointing it out!

  9. Paul Sun on 2014-12-4

    In the first for loop I can get the min and max number of the array, beside put them in hash. Then I can loop through from min through max to see where longest consecutive sequence is. I think this way would be clear. If the number is very scattered, the complexity can not be much bigger than O(n).

  10. Aaron Zhang on 2015-1-3

    who tells u complexity of contain is O(1)? check this http://en.wikipedia.org/wiki/Hash_table

  11. rs on 2015-1-10

    What do you mean by n == m? It doesn’t seem to me to be possible unless the whole set contains a whole consecutive sequence, in which case the runtime is still O(n). The example{1,3,5,7,9} in the article doesn’t seem to satisfy this condition?

  12. PK on 2015-1-27

    for (int e : num)
    set.add(e);

    Above code will use O(N) time right? where N is number of elements in array num. Yes add operation takes constant time O(1) to add an element in a hash set with perfect hash function, but if we repeat an operation of O(1) in a loop for N times it will have time complexity of O(N) as it time taken will grow/shrink with value of N. Am i understanding it correctly?

  13. PK on 2015-1-29

    post http://codeluli.blogspot.in/2013/02/longest-consecutive-sequence.html has a solution with runtime complexity O(N) :).

  14. Tony Wang on 2015-3-3

    If ‘set.contains(…)’ is O(1) then whole solution can be considered as O(n).
    Another solution without using of Hash is do sorting first, the average complexity will be O(NlogN), plus an O(n) to find out longest sequence.

  15. ygw on 2015-3-22

    Adding “if(!set.contains(e)) continue” after the second “for” line appears to make it completely O(n).

  16. Vimukthi Weerasiri on 2015-7-15

    why dont you iterate throw the set, rather than the array? It will avoid checking for the duplicate values in array.

  17. dawei su on 2015-7-24

    why not remove(num) after each checking? It will not affect the result anyway. Then for the extreme case you will also get O(N).

  18. coder on 2015-10-29

    I seriously doubt the correctness of this code for input array { 4,0,1,2,16,12,13,14,15,5,6,7,8,9,10};

  19. animesh on 2015-11-4

    I don’t think this was the actual question.

    If you see the example given in leetcode,

    [10, 9, 2, 5, 3, 7, 101, 18],

    for this it takes the longest subsequence as [2, 5, 7, 101]

    It doesn’t take into account the higher numbers which came previously.

    Have you tried running the code in leetcode?

    the example you have given, [100, 4, 200, 1, 3, 2]

    when run in leetcode, gives the answer as 2 i.e., 100 and 200
    whereas you say the answer is 4.

  20. animesh on 2015-11-6

    the valid subsequences will [100,200], [4,200], [1,3], [1,2]
    All these are valid longest increasing sub sequence. But the answer can’t be 4.

  21. Renzo Nuccitelli on 2016-2-12

    I had the same idea. But for huge number as max and min the running time would be terrible. Imagine [-10ˆ1000000000000000, 10ˆ1000000000000000]. Only two numbers on list and you would take a bunch of time. So it would be O(max-min). It would, but hash seem be better in this case

  22. Renzo Nuccitelli on 2016-2-12

    I took sometime to get in same conclusion of using a hash set. This is my solution in Python: https://github.com/renzon/code_interview_training/blob/master/longest_consecutive_sequence.py. I iterate over set itself and stop once I reach a interval its length is bigger than the number of elements on set.

  23. Eugene Arnatovich on 2016-3-5


    //Longest Consecutive Sequence (Java)
    // Note: this is longest "consecutive" elements sequence, i.e., 1,2,3,4 is correct since difference
    // between neighbors is 1, e.g. 4-3=1, 3-2=1, and so
    public int solution(int[] arr){
    Set tree = new TreeSet();
    for (int a : arr) {
    tree.add(a);
    }
    Integer[] newarr = new Integer[myarr.length];
    tree.toArray(newarr);
    int ans = 1;
    int max = ans;
    for (int i = 1; i ans) {
    ans = max;
    }
    }
    return ans;
    }

  24. Matias SM on 2016-4-10

    TreeSet is a balanced search tree (guarantees log N cost operations). Thus, the total insertion cost is N log N (required time complexity is O(N)

  25. Matias SM on 2016-4-10

    Is this comment about an old implementation? in the given example m = 1 (not n). And, following the code, what would happen would be that each “set.contains” would return false, and the whole array will be iterated once more => the complexity would be O(N). What am I missing?

  26. Vaibhav Gupta on 2016-7-27

    for input {8,7,6,5,4,3,2,1} the complexity of this solution will be O(n^2). The second for loop, when run with e=8 will remove all the elements from the set. Thus, for e=8, the while loop that runs, will be of O(n) and after that, the for loop will still iterator for other 7 values (though each time it will return false for set.contains(left)) but still the for loop will run n times nonetheless. The worst case complexity of this solution is thus O(n^2) and not O(n).

  27. rupalph on 2016-7-31

    I think a check can be added if max > set.size() then loop should break.

  28. Wang Shuhao on 2016-8-1

    what if the array has duplicate numbers?

  29. ryanlr on 2016-8-3

    For input {8,7,6,5,4,3,2,1}, the first loop time is 8, the second is 1 because [7..1] are removed, same for the left iterations.

  30. kayal on 2017-5-6

    Curious.. can we use priority queue to add the elements in sorted orde, the offer complexity is o(log n) and then check if its consecutive which will just be o(n).
    Anyone tell me why this isnt o(n)?

Leave a comment

*