Find the length of the longest run of consecutive values in an unsorted array.
Start with the concrete trace below. It shows the state the algorithm must carry as it runs.
Problem trace
Longest Consecutive Sequence: Only values without a predecessor start a run; then advance one value at a time.
Input and goalFind the length of the longest run of consecutive values in an unsorted array.
Build the membership setDeduplicate nums into {1,2,3,4,100,200}; best starts at 0. Sorted display does not change set membership or the answer.
next candidate 11021324310042005
examplenums = [100, 4, 200, 1, 3, 2]; set displayed in sorted ordermapLabelscalar state and membership queryset{1,2,3,4,100,200}
scalar state and membership querybest0
Recognize start 1For candidate 1, predecessor 0 is absent, so initialize end=1 and enter the while loop.
start=1end=11021324310042005
examplenums = [100, 4, 200, 1, 3, 2]; set displayed in sorted ordermapLabelscalar state and membership querybranchstart a run
scalar state and membership querybest0query0 absent
Advance end to 2end+1=2 is in the set, so the while loop moves end from 1 to 2.
start=110end: 1 -> 221324310042005
examplenums = [100, 4, 200, 1, 3, 2]; set displayed in sorted ordermapLabelscalar state and membership queryrunLength2 - 1 + 1 = 2
scalar state and membership querybest0query2 present
Advance end to 3end+1=3 is present, so end moves from 2 to 3.
start=11021end: 2 -> 3324310042005
examplenums = [100, 4, 200, 1, 3, 2]; set displayed in sorted ordermapLabelscalar state and membership queryrunLength3 - 1 + 1 = 3
scalar state and membership querybest0query3 present
Advance end to 4end+1=4 is present, so end moves from 3 to 4.
start=1102132end: 3 -> 44310042005
examplenums = [100, 4, 200, 1, 3, 2]; set displayed in sorted ordermapLabelscalar state and membership queryrunLength4 - 1 + 1 = 4
scalar state and membership querybest0query4 present
Stop the run and update bestend+1=5 is absent. The completed length is 4-1+1=4, so best changes from 0 to 4.
start=1102132end=44310042005
examplenums = [100, 4, 200, 1, 3, 2]; set displayed in sorted ordermapLabelscalar state and membership queryarithmeticmax(0, 4 - 1 + 1) = 4
scalar state and membership querybest4query5 absent
Skip candidate 2For candidate 2, predecessor 1 is present. Continue immediately so the run [1,2,3,4] is not counted again.
10skip start=22132completed end=44310042005
examplenums = [100, 4, 200, 1, 3, 2]; set displayed in sorted ordermapLabelscalar state and membership querybranchcontinue
scalar state and membership querybest4query1 present
Skip candidate 3For candidate 3, predecessor 2 is present, so continue.
1021skip start=332completed end=44310042005
examplenums = [100, 4, 200, 1, 3, 2]; set displayed in sorted ordermapLabelscalar state and membership querybranchcontinue
scalar state and membership querybest4query2 present
Skip candidate 4For candidate 4, predecessor 3 is present, so continue.
102132skip start=4completed end=44310042005
examplenums = [100, 4, 200, 1, 3, 2]; set displayed in sorted ordermapLabelscalar state and membership querybranchcontinue
scalar state and membership querybest4query3 present
Measure singleton 100For 100, predecessor 99 is absent, but successor 101 is also absent. Its length is 100-100+1=1, so best stays 4.
10213243start=100end=10010042005
examplenums = [100, 4, 200, 1, 3, 2]; set displayed in sorted ordermapLabelscalar state and membership queryarithmeticmax(4, 100 - 100 + 1) = 4
scalar state and membership querybest4queries99 absent; 101 absent
Measure singleton 200For 200, predecessor 199 and successor 201 are absent. Its length is 1, so best remains 4.
102132431004start=200end=2002005
examplenums = [100, 4, 200, 1, 3, 2]; set displayed in sorted ordermapLabelscalar state and membership queryarithmeticmax(4, 200 - 200 + 1) = 4
scalar state and membership querybest4queries199 absent; 201 absent
Return the longest lengthAll set values are either a measured run start or were skipped because their predecessor exists. Return best=4.
best run start102132best run end4310042005
examplenums = [100, 4, 200, 1, 3, 2]; set displayed in sorted ordermapLabelscalar state and membership querylongestRun[1,2,3,4]result4
scalar state and membership querybest4
Recognize it
The input is unsorted and asks for consecutive integer values, not consecutive positions, while near-linear time rules out sorting as the intended mechanism.
Keep true
A run is expanded only from its unique smallest value, identified by missing predecessor; best is the maximum completed run length seen so far.
Reuse it
Before expanding a component, find a unique boundary that only one member can satisfy; this avoids duplicate work in runs, intervals, and component scans.
Read it this way: Deduplicate nums into {1,2,3,4,100,200}; best starts at 0. Sorted display does not change set membership or the answer. Step through the frames to watch the state change. The last frame shows the answer or the stopping condition.
Pattern: Set.
Simple idea: Start counting only when value - 1 is missing. That means the value is the
start of a run. Each run is counted once.
def longest_consecutive(nums: list[int]) -> int: values = set(nums) best = 0 for start in values: if start - 1 in values: continue end = start while end + 1 in values: end += 1 best = max(best, end - start + 1) return best