Longest Consecutive Sequence
Length of the longest run of consecutive integers in O(N) using a hash set.
3 min read
hash-set union-find
Problem#
Given an unsorted array nums, return the length of the longest sequence of consecutive integers (regardless of position in nums). Must run in O(N).
Examples#
[100,4,200,1,3,2]→4([1,2,3,4]).[0,3,7,2,5,8,4,6,0,1]→9([0..8]).
Constraints#
0 <= nums.length <= 10^5,-10^9 <= nums[i] <= 10^9.
Hints#
Hint
Only start counting from values where
v - 1 is absent — guarantees each sequence is counted once. Approach#
Put all values in an unordered_set. For each v, if v - 1 is not in the set, v is a sequence start: walk forward v, v+1, v+2, ... while present and update best length.
Solution#
class Solution {public: int longestConsecutive(vector<int>& nums) { unordered_set<int> s(nums.begin(), nums.end()); int best = 0; for (int v : s) { if (s.count(v - 1)) continue; // not a start int cur = v, len = 1; while (s.count(cur + 1)) { ++cur; ++len; } best = max(best, len); } return best; }};func longestConsecutive(nums []int) int { s := map[int]bool{} for _, v := range nums { s[v] = true } best := 0 for v := range s { if s[v-1] { continue } cur, length := v, 1 for s[cur+1] { cur++ length++ } if length > best { best = length } } return best}from typing import List
class Solution: def longestConsecutive(self, nums: List[int]) -> int: s = set(nums) best = 0 for v in s: if v - 1 in s: continue cur, length = v, 1 while cur + 1 in s: cur += 1 length += 1 if length > best: best = length return bestfunction longestConsecutive(nums) { const s = new Set(nums); let best = 0; for (const v of s) { if (s.has(v - 1)) continue; let cur = v, len = 1; while (s.has(cur + 1)) { cur++; len++; } if (len > best) best = len; } return best;}class Solution { public int longestConsecutive(int[] nums) { Set<Integer> s = new HashSet<>(); for (int v : nums) s.add(v); int best = 0; for (int v : s) { if (s.contains(v - 1)) continue; int cur = v, len = 1; while (s.contains(cur + 1)) { cur++; len++; } if (len > best) best = len; } return best; }}function longestConsecutive(nums: number[]): number { const s = new Set(nums); let best = 0; for (const v of s) { if (s.has(v - 1)) continue; let cur = v, len = 1; while (s.has(cur + 1)) { cur++; len++; } if (len > best) best = len; } return best;}Editorial#
The “only count from sequence starts” guard is what gives O(N) total work — without it, you’d walk each sequence from every member quadratically. Each value is visited at most twice total: once as a non-start (skipped) and at most once as part of a forward walk.
Complexity#
- Time: O(N) amortized.
- Space: O(N).
Concept revision#
Related#