6
set size
Find the length of the longest run of consecutive integers in an unsorted array — in O(n)time by using a hash set to skip anything that isn't the first number of its run.
Given an unsorted array of integers, return the length of the longest consecutive sequence (e.g. 4, 5, 6, 7has length 4). Duplicates don't extend a run. For [100, 4, 200, 1, 3, 2] the answer is 4 — the sequence 1, 2, 3, 4.
v is the start of a consecutive run iff v - 1 is not in the set. Skip every other value. Then walk v, v+1, v+2, … with O(1) set lookups until the chain breaks. Each value is visited at most once total, giving O(n) — no sorting needed.new Set(nums) takes O(n) and gives O(1) lookups. Duplicates collapse — that's fine.v in the set, check if v - 1 is present.set.has(v - 1), v is a middle/end value — skip it entirely. This is the key savings.cur while set.has(cur + 1), counting the length.best = Math.max(best, run) after each run ends.while loop even begins.The while loop looks like it could walk O(n) per start. But we only enter a walk from a sequence start. Each element belongs to exactly one run and is visited at most once across all walks. Total work is O(n).
Set from [100, 4, 200, 1, 3, 2]. O(1) membership checks let us avoid sorting entirely.function longestConsecutive(nums: number[]): number {
const set = new Set<number>(nums);
let best = 0;
for (const v of set) {
// Only begin a walk from sequence STARTS (no left neighbour).
if (set.has(v - 1)) continue;
let cur = v;
let run = 1;
while (set.has(cur + 1)) {
cur++;
run++;
}
best = Math.max(best, run);
}
return best;
}Set<number>costs O(n) and enables O(1) membership checks everywhere below. Duplicates are silently deduplicated — they can't extend a consecutive run.set (not nums) to avoid processing duplicate values twice. if (set.has(v - 1)) continueskips any value that has a left neighbour — it's provably not the start of its run. This single line is responsible for the O(n) guarantee.cur while the next integer exists in the set. Each step costs O(1). The total steps across all runs equal exactly the number of distinct values, so the total across all iterations is O(n).Math.max is O(1). Return best when done.while looks quadratic but the start-check ensures total iterations across all walks equal n.bestStart alongside best; after the loop reconstruct with Array.from({length: best}, (_, i) => bestStart + i).nums.includes(v + k)scan for k = 1, 2, …. That's O(n²) or O(n³) depending on inner loop implementation.| "longest consecutive" or "consecutive run" | hash set + start-only walk |
| unsorted array, O(n) required | Set for O(1) membership, skip non-starts |
| temptation to sort first | ask: can a set skip the redundant work? |
| "how many distinct runs / components" | start-check + walk per component |
function longestConsecutive(nums: number[]): number {
const set = new Set<number>(nums);
let best = 0;
for (const v of set) {
if (set.has(v - 1)) continue; // skip: not a start
let cur = v, run = 1;
while (set.has(cur + 1)) { cur++; run++; }
best = Math.max(best, run);
}
return best;
}Set<number> from the input array — enables O(1) lookups and collapses duplicates.nums = [100, 4, 200, 1, 3, 2], which values are sequence starts?