Bird
Raised Fist0
Interview Prephash-maps-setsmediumAmazonFacebookGoogleBloomberg

Longest Consecutive Sequence

Choose your preparation mode4 modes available
🎯
Longest Consecutive Sequence
mediumHASH_MAPAmazonFacebookGoogle

Imagine you have a messy list of dates when a user logged into a system, and you want to find the longest streak of consecutive login days to reward loyalty.

💡 This problem tests your ability to efficiently find sequences in an unsorted array. Beginners often struggle because the naive approach is slow and they don't immediately see how to use a hash set to speed up membership checks.
📋
Problem Statement

Given an unsorted array of integers nums, return the length of the longest consecutive elements sequence. Your algorithm must run in O(n) time.

1 ≤ nums.length ≤ 10^5-10^9 ≤ nums[i] ≤ 10^9
💡
Example
Input"[100, 4, 200, 1, 3, 2]"
Output4

The longest consecutive sequence is [1, 2, 3, 4].

  • All elements are the same → output is 1
  • Array with one element → output is 1
  • Array with no consecutive numbers → output is 1
  • Array with negative and positive numbers → correctly find longest sequence
⚠️
Common Mistakes
Checking consecutive numbers by scanning array instead of using a hash set

Leads to O(n^2) time and TLE on large inputs

✅ Use a hash set for O(1) membership checks

Not skipping duplicates after sorting

Incorrectly counts duplicates as consecutive, inflating sequence length

✅ Add a condition to skip duplicates during linear scan

Starting to count sequences from every number instead of only sequence starts

Redundant counting causes inefficiency and possible TLE

✅ Only start counting if number-1 is not in the set

Not handling empty input array

Code may crash or return wrong result

✅ Add explicit check for empty input and return 0

Using sorting without considering negative numbers or large ranges

May cause incorrect results or inefficiency

✅ Sorting works regardless of sign; just ensure stable numeric sort

🧠
Brute Force (Nested Loops)
💡 Starting with brute force helps understand the problem deeply by trying all possibilities, even though it's inefficient.

Intuition

Check for every number how long the consecutive sequence starting from it is by incrementing and searching for next numbers.

Algorithm

  1. For each number in the array, start counting consecutive numbers incrementally.
  2. Check if the next consecutive number exists in the array by scanning it.
  3. Keep track of the longest consecutive count found so far.
  4. Return the maximum count after checking all numbers.
💡 This approach is straightforward but inefficient because it repeatedly scans the array for each number, leading to many redundant checks.
</>
Code
def longestConsecutive(nums):
    max_len = 0
    for num in nums:
        length = 1
        current = num + 1
        while current in nums:
            length += 1
            current += 1
        max_len = max(max_len, length)
    return max_len

# Driver code
if __name__ == '__main__':
    print(longestConsecutive([100, 4, 200, 1, 3, 2]))  # Output: 4
Line Notes
for num in nums:Iterate over each number to consider it as a potential sequence start
while current in nums:Check if the next consecutive number exists by scanning the list (slow)
length += 1Increment length for each consecutive number found
max_len = max(max_len, length)Update the maximum length found so far
import java.util.*;
public class Solution {
    public static int longestConsecutive(int[] nums) {
        int maxLen = 0;
        for (int num : nums) {
            int length = 1;
            int current = num + 1;
            while (contains(nums, current)) {
                length++;
                current++;
            }
            maxLen = Math.max(maxLen, length);
        }
        return maxLen;
    }
    private static boolean contains(int[] nums, int target) {
        for (int n : nums) {
            if (n == target) return true;
        }
        return false;
    }
    public static void main(String[] args) {
        int[] nums = {100, 4, 200, 1, 3, 2};
        System.out.println(longestConsecutive(nums)); // Output: 4
    }
}
Line Notes
for (int num : nums)Loop over each number to try as sequence start
while (contains(nums, current))Check existence of next consecutive number by scanning array
length++Increment length for each consecutive number found
maxLen = Math.max(maxLen, length)Keep track of the longest sequence length
#include <iostream>
#include <vector>
using namespace std;

bool contains(const vector<int>& nums, int target) {
    for (int n : nums) {
        if (n == target) return true;
    }
    return false;
}

int longestConsecutive(vector<int>& nums) {
    int maxLen = 0;
    for (int num : nums) {
        int length = 1;
        int current = num + 1;
        while (contains(nums, current)) {
            length++;
            current++;
        }
        maxLen = max(maxLen, length);
    }
    return maxLen;
}

int main() {
    vector<int> nums = {100, 4, 200, 1, 3, 2};
    cout << longestConsecutive(nums) << endl; // Output: 4
    return 0;
}
Line Notes
for (int num : nums)Try each number as a potential sequence start
while (contains(nums, current))Check if next consecutive number exists by scanning vector
length++Increase length for each found consecutive number
maxLen = max(maxLen, length)Update maximum sequence length found
function longestConsecutive(nums) {
    let maxLen = 0;
    for (let num of nums) {
        let length = 1;
        let current = num + 1;
        while (nums.includes(current)) {
            length++;
            current++;
        }
        maxLen = Math.max(maxLen, length);
    }
    return maxLen;
}

// Test
console.log(longestConsecutive([100, 4, 200, 1, 3, 2])); // Output: 4
Line Notes
for (let num of nums)Iterate over each number to check sequences
while (nums.includes(current))Check if next consecutive number exists by scanning array
length++Increment length for each consecutive number found
maxLen = Math.max(maxLen, length)Track the longest sequence length
⏱
Complexity
TimeO(n^2)
SpaceO(1)

For each number, we scan the entire array to check for consecutive numbers, leading to quadratic time.

💡 For n=20, this means up to 400 checks, which grows quickly and becomes impractical for large n.
Interview Verdict: TLE

This approach is too slow for large inputs and will time out in interviews, but it helps understand the problem.

🧠
Sorting + Linear Scan
💡 Sorting the array first helps by putting numbers in order, so consecutive sequences become adjacent, making it easier to count.

Intuition

Sort the array, then scan once to count lengths of consecutive runs by comparing adjacent elements.

Algorithm

  1. Sort the array.
  2. Initialize max length and current length counters.
  3. Iterate through the sorted array, increment current length if consecutive, else reset.
  4. Return the maximum length found.
💡 Sorting simplifies the problem but costs O(n log n) time; the linear scan then efficiently finds sequences.
</>
Code
def longestConsecutive(nums):
    if not nums:
        return 0
    nums.sort()
    max_len = 1
    current_len = 1
    for i in range(1, len(nums)):
        if nums[i] == nums[i-1]:
            continue  # skip duplicates
        elif nums[i] == nums[i-1] + 1:
            current_len += 1
        else:
            max_len = max(max_len, current_len)
            current_len = 1
    max_len = max(max_len, current_len)
    return max_len

# Driver code
if __name__ == '__main__':
    print(longestConsecutive([100, 4, 200, 1, 3, 2]))  # Output: 4
Line Notes
if not nums:Handle empty input edge case
nums.sort()Sort the array to bring consecutive numbers together
if nums[i] == nums[i-1]:Skip duplicates to avoid counting them multiple times
elif nums[i] == nums[i-1] + 1:Check if current number continues the consecutive sequence
import java.util.*;
public class Solution {
    public static int longestConsecutive(int[] nums) {
        if (nums.length == 0) return 0;
        Arrays.sort(nums);
        int maxLen = 1, currentLen = 1;
        for (int i = 1; i < nums.length; i++) {
            if (nums[i] == nums[i-1]) continue;
            else if (nums[i] == nums[i-1] + 1) currentLen++;
            else {
                maxLen = Math.max(maxLen, currentLen);
                currentLen = 1;
            }
        }
        maxLen = Math.max(maxLen, currentLen);
        return maxLen;
    }
    public static void main(String[] args) {
        int[] nums = {100, 4, 200, 1, 3, 2};
        System.out.println(longestConsecutive(nums)); // Output: 4
    }
}
Line Notes
if (nums.length == 0) return 0;Handle empty input
Arrays.sort(nums);Sort array to group consecutive numbers
if (nums[i] == nums[i-1]) continue;Skip duplicates to avoid false increments
else if (nums[i] == nums[i-1] + 1)Detect consecutive numbers to increment current length
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int longestConsecutive(vector<int>& nums) {
    if (nums.empty()) return 0;
    sort(nums.begin(), nums.end());
    int maxLen = 1, currentLen = 1;
    for (int i = 1; i < nums.size(); i++) {
        if (nums[i] == nums[i-1]) continue;
        else if (nums[i] == nums[i-1] + 1) currentLen++;
        else {
            maxLen = max(maxLen, currentLen);
            currentLen = 1;
        }
    }
    maxLen = max(maxLen, currentLen);
    return maxLen;
}

int main() {
    vector<int> nums = {100, 4, 200, 1, 3, 2};
    cout << longestConsecutive(nums) << endl; // Output: 4
    return 0;
}
Line Notes
if (nums.empty()) return 0;Handle empty input case
sort(nums.begin(), nums.end());Sort to bring consecutive numbers together
if (nums[i] == nums[i-1]) continue;Skip duplicates to avoid counting them multiple times
else if (nums[i] == nums[i-1] + 1)Check if current number continues the consecutive sequence
function longestConsecutive(nums) {
    if (nums.length === 0) return 0;
    nums.sort((a, b) => a - b);
    let maxLen = 1, currentLen = 1;
    for (let i = 1; i < nums.length; i++) {
        if (nums[i] === nums[i-1]) continue;
        else if (nums[i] === nums[i-1] + 1) currentLen++;
        else {
            maxLen = Math.max(maxLen, currentLen);
            currentLen = 1;
        }
    }
    return Math.max(maxLen, currentLen);
}

// Test
console.log(longestConsecutive([100, 4, 200, 1, 3, 2])); // Output: 4
Line Notes
if (nums.length === 0) return 0;Handle empty input edge case
nums.sort((a, b) => a - b);Sort array numerically to group consecutive numbers
if (nums[i] === nums[i-1]) continue;Skip duplicates to avoid false increments
else if (nums[i] === nums[i-1] + 1)Detect consecutive numbers to increment current length
⏱
Complexity
TimeO(n log n)
SpaceO(1) or O(n) depending on sorting implementation

Sorting takes O(n log n), then a single pass O(n) to find longest consecutive sequence.

💡 For n=100000, sorting is feasible but slower than linear solutions; still acceptable in many interviews.
Interview Verdict: Accepted

This approach passes but is not optimal; it is a good intermediate step to show improvement over brute force.

🧠
Optimal Hash Set with Sequence Start Detection
💡 Using a hash set allows O(1) membership checks, enabling a linear time solution by only starting sequences at their minimal element.

Intuition

Put all numbers in a set. For each number, only start counting if it is the start of a sequence (no smaller consecutive number exists). Then count forward until the sequence ends.

Algorithm

  1. Insert all numbers into a hash set for O(1) lookups.
  2. Iterate over each number; if number-1 is not in the set, this number is a sequence start.
  3. From each start, count consecutive numbers by checking number+1, number+2, etc. in the set.
  4. Track and update the maximum sequence length found.
  5. Return the maximum length after processing all numbers.
💡 This approach avoids redundant work by only counting sequences from their smallest element, ensuring linear time complexity.
</>
Code
def longestConsecutive(nums):
    num_set = set(nums)
    max_len = 0
    for num in num_set:
        if num - 1 not in num_set:
            current_num = num
            length = 1
            while current_num + 1 in num_set:
                current_num += 1
                length += 1
            max_len = max(max_len, length)
    return max_len

# Driver code
if __name__ == '__main__':
    print(longestConsecutive([100, 4, 200, 1, 3, 2]))  # Output: 4
Line Notes
num_set = set(nums)Create a hash set for O(1) membership checks
for num in num_set:Iterate over unique numbers only
if num - 1 not in num_set:Check if current number is start of a sequence
while current_num + 1 in num_set:Count consecutive numbers forward efficiently
import java.util.*;
public class Solution {
    public static int longestConsecutive(int[] nums) {
        Set<Integer> numSet = new HashSet<>();
        for (int num : nums) numSet.add(num);
        int maxLen = 0;
        for (int num : numSet) {
            if (!numSet.contains(num - 1)) {
                int currentNum = num;
                int length = 1;
                while (numSet.contains(currentNum + 1)) {
                    currentNum++;
                    length++;
                }
                maxLen = Math.max(maxLen, length);
            }
        }
        return maxLen;
    }
    public static void main(String[] args) {
        int[] nums = {100, 4, 200, 1, 3, 2};
        System.out.println(longestConsecutive(nums)); // Output: 4
    }
}
Line Notes
Set<Integer> numSet = new HashSet<>();Use hash set for O(1) lookups
for (int num : numSet)Iterate over unique numbers only
if (!numSet.contains(num - 1))Identify sequence starts by absence of predecessor
while (numSet.contains(currentNum + 1))Count consecutive numbers efficiently
#include <iostream>
#include <vector>
#include <unordered_set>
using namespace std;

int longestConsecutive(vector<int>& nums) {
    unordered_set<int> numSet(nums.begin(), nums.end());
    int maxLen = 0;
    for (int num : numSet) {
        if (numSet.find(num - 1) == numSet.end()) {
            int currentNum = num;
            int length = 1;
            while (numSet.find(currentNum + 1) != numSet.end()) {
                currentNum++;
                length++;
            }
            maxLen = max(maxLen, length);
        }
    }
    return maxLen;
}

int main() {
    vector<int> nums = {100, 4, 200, 1, 3, 2};
    cout << longestConsecutive(nums) << endl; // Output: 4
    return 0;
}
Line Notes
unordered_set<int> numSet(nums.begin(), nums.end());Initialize hash set for O(1) membership
for (int num : numSet)Iterate over unique elements only
if (numSet.find(num - 1) == numSet.end())Check if current number is sequence start
while (numSet.find(currentNum + 1) != numSet.end())Count consecutive numbers forward efficiently
function longestConsecutive(nums) {
    const numSet = new Set(nums);
    let maxLen = 0;
    for (const num of numSet) {
        if (!numSet.has(num - 1)) {
            let currentNum = num;
            let length = 1;
            while (numSet.has(currentNum + 1)) {
                currentNum++;
                length++;
            }
            maxLen = Math.max(maxLen, length);
        }
    }
    return maxLen;
}

// Test
console.log(longestConsecutive([100, 4, 200, 1, 3, 2])); // Output: 4
Line Notes
const numSet = new Set(nums);Create a set for O(1) membership checks
for (const num of numSet)Iterate over unique numbers only
if (!numSet.has(num - 1))Detect sequence starts by checking absence of predecessor
while (numSet.has(currentNum + 1))Count consecutive numbers efficiently
⏱
Complexity
TimeO(n)
SpaceO(n)

Each number is processed at most twice: once when checking if it's a sequence start, and once when counting forward.

💡 For n=100000, this means roughly 200000 operations, which is efficient and scalable.
Interview Verdict: Accepted

This is the optimal and recommended approach for interviews, demonstrating mastery of hash sets and sequence detection.

📊
All Approaches - One-Glance Tradeoffs
💡 In 95% of interviews, code the optimal hash set approach; mention brute force and sorting to show progression.
ApproachTimeSpaceStack RiskReconstructUse In Interview
1. Brute ForceO(n^2)O(1)NoNoMention only - never code
2. Sorting + Linear ScanO(n log n)O(1) or O(n)NoYesGood intermediate step if stuck
3. Optimal Hash SetO(n)O(n)NoYesCode this in 95% of interviews
💼
Interview Strategy
💡 Use this guide to understand the problem deeply, practice coding all approaches, and prepare to explain tradeoffs clearly in interviews.

How to Present

Clarify the problem and constraints with the interviewer.Start with the brute force approach to show understanding.Improve to sorting-based approach to optimize time.Present the optimal hash set approach as the final solution.Write clean code and test with edge cases.

Time Allocation

Clarify: 2min → Approach: 5min → Code: 10min → Test: 3min. Total ~20min

What the Interviewer Tests

The interviewer tests your problem-solving progression, ability to optimize, and knowledge of hash sets and sequence detection.

Common Follow-ups

  • What if duplicates are present? → Skip duplicates in sorting or use set.
  • Can you reconstruct the actual longest sequence? → Store sequence starts and build sequence.
  • What if input is a stream? → Use dynamic data structures or sliding window.
  • How to handle very large ranges? → Use hash sets, avoid sorting.
💡 These follow-ups test your ability to handle variations and extensions of the problem, common in interviews.
🔍
Pattern Recognition

When to Use

1) Need to find consecutive sequences in unsorted data; 2) O(n) time required; 3) Hash set membership checks possible; 4) Sequence start detection is feasible.

Signature Phrases

'longest consecutive elements sequence''unsorted array''must run in O(n) time'

NOT This Pattern When

Sorting-based problems without membership checks or problems requiring subsequence (not necessarily consecutive) detection

Similar Problems

Longest Increasing Subsequence - similar but order matters and not necessarily consecutiveMaximum Consecutive Ones - simpler consecutive counting in binary arraysLongest Consecutive Path in a Matrix - similar concept extended to 2D

Practice

(1/5)
1. Given an array of integers and an integer k, you need to determine if the array can be partitioned into pairs such that the sum of each pair is divisible by k. Which approach guarantees an optimal solution with linear time complexity?
easy
A. Use a frequency map to count remainders modulo k and verify complementary counts.
B. Check all pairs with nested loops to find valid pairs.
C. Use dynamic programming to find subsets whose sums are divisible by k.
D. Use a greedy approach by pairing elements with the smallest remainder first.

Solution

  1. Step 1: Understand the problem constraints

    The problem requires pairing elements so that each pair sums to a multiple of k. This depends on the remainders of elements modulo k.
  2. Step 2: Identify the approach that efficiently tracks remainder frequencies

    Using a frequency map of remainders allows pairing elements with complementary remainders (e.g., remainder r pairs with k-r). This approach runs in O(n) time and uses O(k) space.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Frequency map approach matches the optimal solution pattern [OK]
Hint: Frequency map of remainders solves pairing optimally [OK]
Common Mistakes:
  • Assuming greedy pairing by smallest remainder always works
  • Using DP which is unnecessary and inefficient here
  • Brute force nested loops for large inputs
2. Given a string s and a pattern p, you need to find all start indices of p's anagrams in s. Which algorithmic approach guarantees an optimal solution with linear time complexity?
easy
A. Sliding window with two frequency counters and a match count to track when all character frequencies match.
B. Brute force checking all substrings of length equal to p and comparing frequency maps each time.
C. Dynamic programming to build a table of substring matches based on previous computations.
D. Greedy approach that tries to match characters from left to right without backtracking.

Solution

  1. Step 1: Understand the problem constraints

    We need to find all anagrams of p in s efficiently, which requires checking character frequencies in substrings of length len(p).
  2. Step 2: Identify the optimal approach

    Sliding window with two frequency counters and a match count allows updating counts in O(1) per step and checking matches in O(1), leading to O(n) time complexity.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Sliding window with match count is known optimal for this problem [OK]
Hint: Sliding window with match count -> O(n) time [OK]
Common Mistakes:
  • Thinking brute force is efficient enough
  • Confusing DP applicability
  • Believing greedy works for anagrams
3. Consider the following Python function that returns the maximum number of pairs summing to k. What is the returned value when calling maxOperations([1, 2, 3, 4], 5)?
easy
A. 2
B. 1
C. 3
D. 4

Solution

  1. Step 1: Trace iterations for input [1, 2, 3, 4], k=5

    Iteration 1: num=1, complement=4, freq empty -> freq[1]=1
    Iteration 2: num=2, complement=3, freq={1:1} -> freq[2]=1
    Iteration 3: num=3, complement=2, freq[2]=1 > 0 -> count=1, freq[2]=0
    Iteration 4: num=4, complement=1, freq[1]=1 > 0 -> count=2, freq[1]=0
  2. Step 2: Final count returned

    Count is 2 after processing all elements.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Two pairs (1,4) and (2,3) sum to 5 [OK]
Hint: Pairs (1,4) and (2,3) found -> count 2 [OK]
Common Mistakes:
  • Counting pairs multiple times
  • Off-by-one in frequency decrement
  • Confusing complement logic
4. The following code attempts to check if an array can be paired such that sums are divisible by k. Which line contains a subtle bug that causes incorrect results on some inputs?
def canArrange(nums, k):
    if len(nums) % 2 != 0:
        return True
    freq = {}
    for num in nums:
        r = ((num % k) + k) % k
        freq[r] = freq.get(r, 0) + 1
    if freq.get(0, 0) % 2 != 0:
        return False
    for r in freq:
        if r != 0:
            complement = (k - r) % k
            if freq.get(r, 0) != freq.get(complement, 0):
                return False
    if k % 2 == 0 and freq.get(k // 2, 0) % 2 != 0:
        return False
    return True
medium
A. Line 5: computing remainder without adjusting for negative numbers
B. Line 2: returning True when array length is odd
C. Line 8: checking if freq[0] count is even
D. Line 13: checking if freq[k//2] count is even when k is even

Solution

  1. Step 1: Check array length condition

    The code returns True if the array length is odd, but pairing requires even length. This causes incorrect True on odd-length arrays.
  2. Step 2: Verify other lines

    Remainder calculation correctly adjusts for negative numbers. Other checks for freq[0] and freq[k//2] are correct.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Odd length arrays cannot be fully paired, so returning True is a bug [OK]
Hint: Array length must be even to form pairs [OK]
Common Mistakes:
  • Returning True on odd length arrays
  • Not adjusting modulo for negative numbers
  • Ignoring freq[0] or freq[k/2] parity checks
5. Identify the bug in the following code snippet for longest arithmetic subsequence length:
medium
A. Line assigning dp[i][diff] without adding 1 to prev_len
B. Line initializing max_len to 0 instead of 1
C. Line creating dp as list of dicts instead of list of lists
D. Line returning max_len if max_len > 0 else n

Solution

  1. Step 1: Examine dp update line

    dp[i][diff] should be prev_len + 1 to extend the subsequence; missing +1 means subsequence length never grows.
  2. Step 2: Check other lines

    max_len initialization and return line are correct; dp as list of dicts is intentional for difference tracking.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Missing +1 causes incorrect subsequence length calculation [OK]
Hint: dp[i][diff] must increment prev_len by 1 to extend subsequence [OK]
Common Mistakes:
  • Forgetting to add 1 when updating dp[i][diff]
  • Initializing max_len incorrectly
  • Confusing subsequence with subarray
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard