Advertisement
Home Data Structure Arrays Check if an Array Contains Consecutive Integers

Check if an Array Contains Consecutive Integers

0
Advertisement

Title: Check if an Array Contains Consecutive Integers

In this guide, you will learn how to check whether a Java array contains consecutive integers, meaning the values, in some order, form an unbroken run like 4, 5, 6, 7 with no gaps and no repeats. This comes up often in interviews as a warm-up problem that tests whether you can reason about ranges, indices, and duplicates without sorting the array first. We will build a linear-time solution, trace it on a sample input, and cover the edge cases an interviewer expects you to raise.

Understanding the Problem

An array of integers is said to contain consecutive integers if, after arranging its elements in order, each value is exactly one more than the value before it. For example, {5, 3, 4, 1, 2} qualifies because sorting it gives 1, 2, 3, 4, 5. An array like {5, 3, 1, 2} fails because 4 is missing, and {1, 1, 3} fails because 2 is missing even though the element count matches the span of the values.

The naive approach sorts the array and checks adjacent differences, which costs O(n log n) time. The goal in this post is a linear-time approach that avoids sorting by using the minimum and maximum values together with a visited-tracking array.

Approach to Check Consecutive Integers

Here is a step-by-step approach that finds the range of values first, then uses that range to catch duplicates in a single additional pass.

  1. Validate the input: throw an exception if the array is null or empty.
  2. Make a single pass to find the min and max values in the array.
  3. Compute range = max - min + 1. If range does not equal the array length, the values cannot be consecutive, so return false immediately.
  4. Allocate a boolean[] named seen of size range to track which offsets from min have already appeared.
  5. Make a second pass over the array. For each value, compute index = value - min. If seen[index] is already true, a duplicate exists, so return false.
  6. If the second pass completes without finding a duplicate, every slot in seen is filled exactly once, so return true.

Java Program to Check Consecutive Integers

Java
public class ConsecutiveIntegersChecker {

    public static boolean areConsecutive(int[] numbers) {
        if (numbers == null || numbers.length == 0) {
            throw new IllegalArgumentException("Array must not be null or empty");
        }
        if (numbers.length == 1) {
            return true;
        }

        int min = numbers[0];
        int max = numbers[0];
        for (int value : numbers) {
            min = Math.min(min, value);
            max = Math.max(max, value);
        }

        int range = max - min + 1;
        if (range != numbers.length) {
            return false;
        }

        boolean[] seen = new boolean[range];
        for (int value : numbers) {
            int index = value - min;
            if (seen[index]) {
                return false;
            }
            seen[index] = true;
        }

        return true;
    }

    public static void main(String[] args) {
        int[] numbers = {5, 3, 4, 1, 2};
        System.out.println(areConsecutive(numbers));
    }
}

Explanation of the Program

Here is what each part of areConsecutive is doing:

  • areConsecutive first rejects null or empty input, then short-circuits to true for a single-element array since one value is trivially a run of length one.
  • The first for loop tracks min and max using Math.min and Math.max, giving the smallest and largest values in a single pass.
  • range is the number of integers from min to max inclusive. Comparing it to numbers.length catches gaps outright, and sets up the next step to catch duplicates.
  • The seen array is sized to range rather than to numbers.length directly, even though the two are equal at this point. Sizing it this way keeps the intent explicit: every valid offset from min through max gets exactly one slot.
  • In the second loop, value - min maps each array value onto a zero-based index into seen. Marking and checking that slot in the same pass detects a duplicate the first time one appears, without needing a HashSet.

Step-by-Step Trace

Trace the algorithm on numbers = {9, 10, 10, 12, 13}, where min = 9; the expected result is false because the value 10 repeats.

Iterationnumbers[i]index = numbers[i] – minseen[index] (before)seen[index] (after)
190falsetrue
2101falsetrue
3101truereturns false

At the start of each iteration, seen[index] being false means that offset has not appeared yet; the moment an iteration finds it already true, the method stops and returns false without examining the rest of the array.

Examples

The following examples cover a true case, a false case caused by a gap, and a true case using negative numbers.

Example 1: Consecutive Integers in Any Order

Input: {5, 3, 4, 1, 2}. Expected output: true, since sorting the values gives 1, 2, 3, 4, 5 with no gaps.

Java
int[] numbers = {5, 3, 4, 1, 2};
System.out.println(areConsecutive(numbers)); // true

Example 2: Array with a Missing Value

Input: {5, 3, 1, 2}. Expected output: false, since range evaluates to 5 while the array holds only 4 elements, so the method returns before ever allocating seen.

Java
int[] numbers = {5, 3, 1, 2};
System.out.println(areConsecutive(numbers)); // false

Example 3: Negative Integers

Input: {-3, -1, -2, 0, -4}. Expected output: true, because the values span -4 through 0 with no gaps or repeats; the index = value - min trick works the same way regardless of sign.

Java
int[] numbers = {-3, -1, -2, 0, -4};
System.out.println(areConsecutive(numbers)); // true

Common Mistakes to Avoid

These are the mistakes that show up most often when candidates implement this check live.

  • Trusting the range check alone – relying only on max - min + 1 == length wrongly accepts {1, 1, 3} as consecutive, because the range matches the length even though 1 repeats and 2 is missing. Always pair the range check with a seen[] (or HashSet) pass that catches duplicates.
  • Indexing seen with the raw value instead of value – min – using numbers[i] directly as an array index throws ArrayIndexOutOfBoundsException the moment a value is negative or larger than the array length. Always subtract min before indexing.
  • Sorting the input array in place – calling Arrays.sort(numbers) to simplify the check silently reorders the caller’s original array, which can break other code that still expects the original order. Sort a copy, or avoid sorting altogether with the min/max approach.
  • Ignoring overflow when computing the range – max - min + 1 overflows silently when max is near Integer.MAX_VALUE and min is negative, producing a wrapped or negative range that breaks the boolean[] allocation. Promote the subtraction to long before comparing it to the array length.

Edge Cases to Test

Walk through these inputs out loud before an interviewer has to ask.

  • Empty array
  • Single-element array
  • Array with duplicate values
  • Array with a gap in the sequence
  • Negative integers only
  • Mixed negative and positive integers
  • Integer.MIN_VALUE or Integer.MAX_VALUE present
  • Null array reference

Additional Considerations

The algorithm runs in O(n) time: one pass to find min and max, and a second pass to populate and check seen. Extra space is O(n) as well, bounded by range, which can never exceed numbers.length once the range check passes.

A sort-based alternative runs in O(n log n) time but needs only O(1) extra space if the sort happens on a disposable copy of the array, so it is worth mentioning as a fallback when memory matters more than CPU time.

A HashSet<Integer> works as a drop-in replacement for the seen array and removes the need to reason about offsets, at the cost of hashing overhead and boxed Integer objects on every insert.

Interview Follow-up Questions

Once the base solution is working, expect the interviewer to push on these variations.

  • What if the array is already sorted? – a single pass checking that numbers[i + 1] - numbers[i] == 1 for every adjacent pair is enough; no min/max scan or seen array is needed.
  • What if duplicates are allowed as long as the distinct values are consecutive? – load the values into a HashSet<Integer> first, then compare set.size() to max - min + 1 instead of rejecting on the first repeat.
  • What if the numbers arrive as a stream that does not fit in memory? – track a running min, max, count, and sum online; a mismatch between the observed sum and the closed-form sum of a consecutive run from min to max signals a gap or duplicate without storing every value.
  • What if you must solve this with O(1) extra space and cannot modify the array? – compare the sum and the sum of squares of the array against the closed-form sum and sum of squares of a consecutive run from min to max; matching on both is extremely unlikely unless the values truly are consecutive.

Conclusion

Checking whether an array contains consecutive integers comes down to comparing the span of values, max - min + 1, against the array length, then using that span to catch duplicates in a single additional pass. This avoids a full sort while still running in linear time.

Try adapting areConsecutive to return the actual missing value when the check fails, or to work against a sorted stream of input. You can learn more about array-based interview problems on the Arrays category page.