PracHub
QuestionsPremiumCoachesLearningGuidesInterview Prep

Quick Overview

This question evaluates a candidate's competency in algorithm design and data-structure reasoning for detecting n-length consecutive integer sequences, encompassing handling of duplicates, negative values, and dynamic insertions and deletions.

  • Medium
  • Anthropic
  • Coding & Algorithms
  • Software Engineer

Detect n-length consecutive sequences

Company: Anthropic

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: Medium

Interview Round: Technical Screen

Given an unsorted collection of integers and a parameter n > 0, determine whether there exists a set of n distinct integers that form a run of consecutive values (i.e., some x, x+1, ..., x+n- 1) regardless of order. If such a run exists, return any one such run; otherwise, return empty. Follow-ups: (a) Handle duplicates and negative numbers; (b) Achieve near-linear time using appropriate data structures; (c) Adapt the design to an online stream supporting insertions and deletions while answering queries about the existence of an n-length consecutive run.

Quick Answer: This question evaluates a candidate's competency in algorithm design and data-structure reasoning for detecting n-length consecutive integer sequences, encompassing handling of duplicates, negative values, and dynamic insertions and deletions.

Part 1: Detect a consecutive run in an unsorted distinct array

You are given an unsorted array of distinct non-negative integers and a positive integer n. Determine whether the array contains n distinct integers that form a consecutive run, such as x, x+1, ..., x+n-1, regardless of their order in the input. Return that run in increasing order. If multiple valid runs exist, return the one with the smallest starting value. If no such run exists, return an empty list.

Constraints

  • 0 <= len(nums) <= 100000
  • 0 <= nums[i] <= 10^9
  • All values in nums are distinct
  • 1 <= n <= 100000

Examples

Input: ([8, 1, 4, 3, 2], 4)

Expected Output: [1, 2, 3, 4]

Explanation: The numbers 1, 2, 3, and 4 are all present.

Input: ([10, 6, 7, 8, 20], 3)

Expected Output: [6, 7, 8]

Explanation: The array contains one run of length 3 starting at 6.

Input: ([5, 9, 1], 2)

Expected Output: []

Explanation: No two distinct values form a consecutive pair.

Input: ([], 1)

Expected Output: []

Explanation: An empty array cannot contain any run.

Input: ([42], 1)

Expected Output: [42]

Explanation: Any single value forms a consecutive run of length 1.

Solution

def solution(nums, n):
    if n <= 0 or not nums or n > len(nums):
        return []

    nums = sorted(nums)
    if n == 1:
        return [nums[0]]

    streak_len = 1
    for i in range(1, len(nums)):
        if nums[i] == nums[i - 1] + 1:
            streak_len += 1
        else:
            streak_len = 1

        if streak_len >= n:
            end = nums[i]
            start = end - n + 1
            return list(range(start, end + 1))

    return []

Time complexity: O(m log m), where m = len(nums). Space complexity: O(m).

Hints

  1. Sorting the numbers can turn the problem into finding a long enough consecutive streak.
  2. Because all values are distinct in this version, you only need to compare adjacent sorted elements.

Part 2: Detect a consecutive run with duplicates and negative numbers

You are given an unsorted array of integers and a positive integer n. The array may contain duplicates and negative numbers. Determine whether there exist n distinct integers that form a consecutive run, such as x, x+1, ..., x+n-1. Duplicates do not increase the length of a run. Return the valid run with the smallest starting value in increasing order. If no such run exists, return an empty list.

Constraints

  • 0 <= len(nums) <= 100000
  • -10^9 <= nums[i] <= 10^9
  • Duplicates may appear in nums
  • 1 <= n <= 100000

Examples

Input: ([-2, -1, -1, 0, 4, 5], 3)

Expected Output: [-2, -1, 0]

Explanation: After ignoring duplicates, -2, -1, and 0 form a valid run.

Input: ([3, 3, 2, 1, 10], 3)

Expected Output: [1, 2, 3]

Explanation: The duplicate 3 should count only once.

Input: ([5, 4, 4, -1, 0, 1], 2)

Expected Output: [-1, 0]

Explanation: Several runs exist, and the smallest starting value is -1.

Input: ([-5, -3, -3, -1], 2)

Expected Output: []

Explanation: No two distinct consecutive integers exist.

Input: ([], 4)

Expected Output: []

Explanation: An empty input cannot contain a run.

Solution

def solution(nums, n):
    if n <= 0 or not nums:
        return []

    values = sorted(set(nums))
    if not values or n > len(values):
        return []
    if n == 1:
        return [values[0]]

    streak_len = 1
    for i in range(1, len(values)):
        if values[i] == values[i - 1] + 1:
            streak_len += 1
        else:
            streak_len = 1

        if streak_len >= n:
            end = values[i]
            start = end - n + 1
            return list(range(start, end + 1))

    return []

Time complexity: O(m log m), where m = len(nums). Space complexity: O(m).

Hints

  1. Duplicates should be ignored when deciding whether values are consecutive.
  2. After removing duplicates, a sorted scan works even when numbers are negative.

Part 3: Find a consecutive run in near-linear time

You are given an unsorted array of integers and a positive integer n. The array may contain duplicates and negative numbers. Return the consecutive run of length n with the smallest starting value, or [] if no such run exists. Your goal is to design an average-case near-linear-time solution, so sorting the full input is not the intended approach.

Constraints

  • 0 <= len(nums) <= 200000
  • -10^9 <= nums[i] <= 10^9
  • Duplicates may appear in nums
  • 1 <= n <= 200000

Examples

Input: ([100, 4, 200, 1, 3, 2], 4)

Expected Output: [1, 2, 3, 4]

Explanation: The classic consecutive run 1 through 4 is present.

Input: ([10, 11, 12, 1, 2, 3, 4], 3)

Expected Output: [1, 2, 3]

Explanation: Both 1-3 and 10-12 work, so return the smaller start.

Input: ([-2, -1, 0, 50, 51, 52], 3)

Expected Output: [-2, -1, 0]

Explanation: Negative values work exactly the same as positive ones.

Input: ([7, 7, 7], 2)

Expected Output: []

Explanation: Only one distinct value is present.

Input: ([9, 2, 5], 1)

Expected Output: [2]

Explanation: For n = 1, return the smallest present value.

Solution

def solution(nums, n):
    if n <= 0 or not nums:
        return []

    values = set(nums)
    if not values or n > len(values):
        return []

    best_start = None

    for x in values:
        if x - 1 in values:
            continue

        y = x
        while y in values:
            y += 1

        if y - x >= n and (best_start is None or x < best_start):
            best_start = x

    if best_start is None:
        return []

    return list(range(best_start, best_start + n))

Time complexity: O(m) average, where m = len(nums). Space complexity: O(m).

Hints

  1. A hash set gives O(1) average membership checks.
  2. Only try to grow a run from values whose predecessor is not present.

Part 4: Maintain consecutive runs in an online stream

You are given a fixed positive integer n and a sequence of online operations over a multiset of integers. Each operation is one of: [1, x] to insert x, [2, x] to delete one occurrence of x if present, or [3, 0] to query whether the current set of distinct values contains a consecutive run of length n. Duplicates matter for insertions and deletions, but a run is still defined using distinct values only. For each query, return the consecutive run of length n with the smallest starting value, or [] if none exists.

Constraints

  • 1 <= n <= 100000
  • 0 <= len(operations) <= 20000
  • -10^9 <= value <= 10^9
  • Delete on a value not currently present should be ignored
  • The stream is a multiset: a value disappears from the distinct set only when its count drops to 0

Examples

Input: (3, [[1, 5], [1, 1], [1, 2], [1, 3], [3, 0], [1, 10], [1, 11], [1, 12], [3, 0]])

Expected Output: [[1, 2, 3], [1, 2, 3]]

Explanation: After the first four inserts, 1-3 exists. Later 10-12 also exists, but 1-3 has the smaller start.

Input: (3, [[1, -1], [1, 0], [1, 1], [1, 1], [3, 0], [2, 0], [3, 0], [2, 1], [3, 0], [1, 0], [3, 0]])

Expected Output: [[-1, 0, 1], [], [], [-1, 0, 1]]

Explanation: Duplicates are counted, so deleting one 1 does not remove the value 1 entirely.

Input: (1, [[3, 0], [1, 2], [3, 0], [1, 2], [2, 2], [3, 0], [2, 2], [3, 0]])

Expected Output: [[], [2], [2], []]

Explanation: For n = 1, any active distinct value is enough.

Input: (4, [[1, 1], [1, 2], [1, 4], [1, 5], [3, 0], [1, 3], [3, 0], [2, 10], [3, 0], [2, 2], [3, 0]])

Expected Output: [[], [1, 2, 3, 4], [1, 2, 3, 4], []]

Explanation: Inserting 3 bridges two intervals into 1-5, and deleting 2 later breaks the length-4 run.

Solution

def solution(n, operations):
    from bisect import bisect_left, bisect_right, insort
    import heapq

    counts = {}
    starts = []
    start_to_end = {}
    end_to_start = {}
    heap = []

    def add_start(s):
        insort(starts, s)

    def remove_start(s):
        i = bisect_left(starts, s)
        if i < len(starts) and starts[i] == s:
            starts.pop(i)

    def push_if_valid(s):
        e = start_to_end.get(s)
        if e is not None and e - s + 1 >= n:
            heapq.heappush(heap, s)

    def insert_value(x):
        counts[x] = counts.get(x, 0) + 1
        if counts[x] > 1:
            return

        left_start = end_to_start.get(x - 1)
        right_end = start_to_end.get(x + 1)

        if left_start is None and right_end is None:
            start_to_end[x] = x
            end_to_start[x] = x
            add_start(x)
            push_if_valid(x)
        elif left_start is not None and right_end is None:
            old_end = x - 1
            start_to_end[left_start] = x
            del end_to_start[old_end]
            end_to_start[x] = left_start
            push_if_valid(left_start)
        elif left_start is None and right_end is not None:
            old_start = x + 1
            end = right_end
            del start_to_end[old_start]
            start_to_end[x] = end
            end_to_start[end] = x
            remove_start(old_start)
            add_start(x)
            push_if_valid(x)
        else:
            old_left_end = x - 1
            old_right_start = x + 1
            right_end_value = start_to_end[old_right_start]
            start_to_end[left_start] = right_end_value
            del end_to_start[old_left_end]
            del start_to_end[old_right_start]
            end_to_start[right_end_value] = left_start
            remove_start(old_right_start)
            push_if_valid(left_start)

    def delete_value(x):
        current = counts.get(x, 0)
        if current == 0:
            return
        if current > 1:
            counts[x] = current - 1
            return

        del counts[x]

        i = bisect_right(starts, x) - 1
        if i < 0:
            return

        s = starts[i]
        e = start_to_end[s]
        if x < s or x > e:
            return

        if s == e == x:
            del start_to_end[s]
            del end_to_start[e]
            remove_start(s)
        elif x == s:
            new_s = s + 1
            del start_to_end[s]
            start_to_end[new_s] = e
            end_to_start[e] = new_s
            remove_start(s)
            add_start(new_s)
            push_if_valid(new_s)
        elif x == e:
            new_e = e - 1
            start_to_end[s] = new_e
            del end_to_start[e]
            end_to_start[new_e] = s
            push_if_valid(s)
        else:
            left_end = x - 1
            right_start = x + 1
            start_to_end[s] = left_end
            end_to_start[left_end] = s
            start_to_end[right_start] = e
            end_to_start[e] = right_start
            add_start(right_start)
            push_if_valid(s)
            push_if_valid(right_start)

    def query():
        while heap:
            s = heap[0]
            e = start_to_end.get(s)
            if e is None or e - s + 1 < n:
                heapq.heappop(heap)
            else:
                return list(range(s, s + n))
        return []

    answers = []
    for op in operations:
        typ = op[0]
        value = op[1] if len(op) > 1 else 0

        if typ == 1:
            insert_value(value)
        elif typ == 2:
            delete_value(value)
        elif typ == 3:
            answers.append(query())

    return answers

Time complexity: Insert/Delete: O(I) due to ordered interval-start maintenance with a Python list; Query: O(log I) amortized with lazy heap cleanup, where I is the number of current intervals. Space complexity: O(U + Q), where U is the number of currently distinct active values and Q is the number of operations.

Hints

  1. Think in terms of maximal consecutive intervals of currently active distinct values.
  2. Keep a count for each value so duplicates only affect the structure when a count changes between 0 and 1.
Last updated: May 21, 2026

Loading coding console...

PracHub

Master your tech interviews with 8,500+ real questions from top companies.

Product

  • Questions
  • Learning Tracks
  • Interview Guides
  • Resources
  • Premium
  • For Universities
  • Student Access

Browse

  • By Company
  • By Role
  • By Category
  • Topic Hubs
  • SQL Questions
  • Compare Platforms
  • Discord Community

Support

  • support@prachub.com
  • (916) 541-4762

Legal

  • Privacy Policy
  • Terms of Service
  • About Us

© 2026 PracHub. All rights reserved.

Related Coding Questions

  • Implement Persistent Memoization LRU Cache - Anthropic (hard)
  • Fix a Corrupted Bootloader Instruction - Anthropic (medium)
  • Implement a Time-Aware Task Manager - Anthropic (hard)
  • Implement a Simplified DNS Resolver - Anthropic (hard)
  • Implement Task Management and Duplicate Detection - Anthropic (medium)