Sorting would make consecutive runs trivial to spot, but that costs O(n log n) and the problem demands linear time. The trick to get there without sorting: put every number in a hash set, then only ever start counting a run from a number that is the start of one โ a number whose predecessor (num - 1) is not in the set. Every element gets examined by at most two constant-time set lookups over the whole algorithm, never revisiting the middle of a run twice.
Sort First
Time O(n log n)Space O(n)Sort the (deduplicated) numbers, then scan once counting how long each run of consecutive values lasts.
class Solution: def longestConsecutive(self, nums: list[int]) -> int: if not nums: return 0 nums = sorted(set(nums)) longest = 1 current = 1 for i in range(1, len(nums)): if nums[i] == nums[i - 1] + 1: current += 1 longest = max(longest, current) else: current = 1 return longestCorrect and only O(n) after sorting, but the sort itself is O(n log n) โ more than the follow-up allows.
Hash Set, Start-of-Sequence Only
OptimalTime O(n)Space O(n)Put every number in a set. For each number, only start extending a sequence if it is a sequence start โ meaning num - 1 is not in the set. From a true start, walk forward (num + 1, num + 2, โฆ) counting how far the run goes. Numbers in the middle of a run are skipped as starting points entirely, so each element is only ever walked over once across the whole algorithm.
class Solution: def longestConsecutive(self, nums: list[int]) -> int: num_set = set(nums) longest = 0 for num in num_set: if num - 1 not in num_set: length = 1 while num + length in num_set: length += 1 longest = max(longest, length) return longestTracing nums = [100, 4, 200, 1, 3, 2] (set built from all six numbers; only sequence starts get expanded):
Hash Map
num=1. Is 0 in the set? No -- 1 is a sequence start. Walk forward.
Numbers 4, 3, and 2 are never used as starting points at all โ each has num - 1 in the set, so the if skips them, which is exactly what keeps the total work linear.
Correctness: every consecutive run has exactly one true start (the number with no predecessor in the set), so every run gets expanded from that start exactly once โ no run is ever counted twice, and no run is ever missed, since every number that is a start is checked.
Complexity: building the set is O(n). Across the whole loop, the inner while only advances through numbers that belong to a run being expanded from its true start, so every number is visited by the inner loop at most once in total โ O(n) time overall, not O(nยฒ). The set holds up to n numbers โ O(n) space.