Menu
DSA interview questionsQuestion 31 of 67

DSA interview question · Question 31 of 67

Longest Consecutive Sequence: Longest Run of Consecutive Integers in O(n)

  • Medium
  • coding
  • ~12 min
  • High relevance
  • 4 min read
  • Updated Oct 2026

Short answer

Put every value in a hash set. A value starts a run only if value - 1 is not in the set; from each such start, count upward while value + 1 is present. Each value is visited at most twice (once in the outer loop, once while extending a run), so the total is O(n) time and O(n) space. Sorting and scanning also works but costs O(n log n).

On this page
  1. Problem
  2. Examples
  3. Approach 1: brute force
  4. Approach 2: optimal
  5. Tests
  6. Edge cases and pitfalls
  7. Where this shows up in data engineering

Problem

Given an unsorted list of integers, return the length of the longest sequence of values v, v+1, v+2, ... that are all present in the list. The values need not be adjacent in the list, and duplicates do not extend a run. Aim for O(n) time. This is widely known as LeetCode 128, Longest Consecutive Sequence.

The list may be empty and may hold up to 10^5 values in the signed 32-bit range.

Examples

nums = [10, 4, 21, 6, 5, 3]   ->  4    (3, 4, 5, 6)
nums = [7, 7, 8]              ->  2    (7, 8; the second 7 does not count)
nums = []                     ->  0
nums = [-1, 1, 0]             ->  3    (-1, 0, 1)

Approach 1: brute force

Sort, then scan once, extending the current run when the next distinct value is one more than the previous and resetting otherwise.

def longest_consecutive_sort(nums):
    if not nums:
        return 0
    vals = sorted(set(nums))
    best = run = 1
    for a, b in zip(vals, vals[1:]):
        run = run + 1 if b == a + 1 else 1
        best = max(best, run)
    return best

Complexity: O(n log n) time, O(n) space. (The truly naive version, starting a run from every value and testing membership in the list, is O(n³).)

Approach 2: optimal

Key insight: only count upward from values that start a run, meaning v - 1 is absent. Every other value is skipped in the outer loop, so each value is touched a bounded number of times.

Walkthrough on [10, 4, 21, 6, 5, 3], set = {3, 4, 5, 6, 10, 21}:

v v - 1 in set? Action Run length
10 no count 10 → 11 missing 1
4 yes skip
21 no count 21 → 22 missing 1
6 yes skip
5 yes skip
3 no count 3, 4, 5, 6 → 7 missing 4
def longest_consecutive(nums):
    values = set(nums)
    best = 0
    for v in values:
        if v - 1 not in values:
            end = v
            while end + 1 in values:
                end += 1
            best = max(best, end - v + 1)
    return best

Iterate over the set, not the original list: with many duplicates of a run start, looping over the list would redo the same count once per copy.

Complexity: O(n) average time, O(n) space. The inner loop runs only from run starts, and runs do not overlap, so across the whole algorithm it advances at most n times in total.

Tests

import random

for f in (longest_consecutive, longest_consecutive_sort):
    assert f([10, 4, 21, 6, 5, 3]) == 4
    assert f([7, 7, 8]) == 2                         # duplicates
    assert f([]) == 0                                # empty
    assert f([42]) == 1                              # single element
    assert f([-1, 1, 0]) == 3                        # negatives
    assert f([5, 5, 5]) == 1                         # all equal
    assert f([2**31 - 1, -2**31]) == 1               # extremes, not consecutive
    assert f([1, 3, 5, 7]) == 1                      # no runs

assert longest_consecutive(list(range(100_000, 0, -1))) == 100_000   # large, reversed

random.seed(9)
for _ in range(300):
    arr = [random.randint(-10, 10) for _ in range(random.randint(0, 15))]
    assert longest_consecutive(arr) == longest_consecutive_sort(arr)

Edge cases and pitfalls

  • Without the v - 1 not in values check, the algorithm counts from every value and becomes O(n²) on a long run.
  • Empty input returns 0, not 1.
  • Duplicates must not lengthen a run; using a set handles that automatically.
  • A while loop that walks downward and upward from every value works too but needs a visited set to stay O(n).

Where this shows up in data engineering

This is the “gaps and islands” problem from SQL: find runs of consecutive dates on which a user was active, or consecutive sequence numbers in a stream to detect missing messages. In SQL the standard trick is value - ROW_NUMBER() OVER (ORDER BY value), which is constant within each island.

By Data Career Hub Editorial · Last reviewed Oct 2026 · Python 3 solutions verified with assert-based tests

Progress is saved in this browser only. No account needed.

Search
Filter by type