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.
- Validate the input: throw an exception if the array is
nullor empty. - Make a single pass to find the
minandmaxvalues in the array. - Compute
range = max - min + 1. Ifrangedoes not equal the array length, the values cannot be consecutive, so returnfalseimmediately. - Allocate a
boolean[]namedseenof sizerangeto track which offsets fromminhave already appeared. - Make a second pass over the array. For each value, compute
index = value - min. Ifseen[index]is alreadytrue, a duplicate exists, so returnfalse. - If the second pass completes without finding a duplicate, every slot in
seenis filled exactly once, so returntrue.
Java Program to Check Consecutive Integers
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:
areConsecutivefirst rejectsnullor empty input, then short-circuits totruefor a single-element array since one value is trivially a run of length one.- The first
forloop tracksminandmaxusingMath.minandMath.max, giving the smallest and largest values in a single pass. rangeis the number of integers frommintomaxinclusive. Comparing it tonumbers.lengthcatches gaps outright, and sets up the next step to catch duplicates.- The
seenarray is sized torangerather than tonumbers.lengthdirectly, even though the two are equal at this point. Sizing it this way keeps the intent explicit: every valid offset fromminthroughmaxgets exactly one slot. - In the second loop,
value - minmaps each array value onto a zero-based index intoseen. Marking and checking that slot in the same pass detects a duplicate the first time one appears, without needing aHashSet.
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.
| Iteration | numbers[i] | index = numbers[i] – min | seen[index] (before) | seen[index] (after) |
|---|---|---|---|---|
| 1 | 9 | 0 | false | true |
| 2 | 10 | 1 | false | true |
| 3 | 10 | 1 | true | returns 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.
int[] numbers = {5, 3, 4, 1, 2};
System.out.println(areConsecutive(numbers)); // trueExample 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.
int[] numbers = {5, 3, 1, 2};
System.out.println(areConsecutive(numbers)); // falseExample 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.
int[] numbers = {-3, -1, -2, 0, -4};
System.out.println(areConsecutive(numbers)); // trueCommon 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 == lengthwrongly accepts{1, 1, 3}as consecutive, because the range matches the length even though1repeats and2is missing. Always pair the range check with aseen[](orHashSet) pass that catches duplicates. - Indexing seen with the raw value instead of value – min – using
numbers[i]directly as an array index throwsArrayIndexOutOfBoundsExceptionthe moment a value is negative or larger than the array length. Always subtractminbefore 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 + 1overflows silently whenmaxis nearInteger.MAX_VALUEandminis negative, producing a wrapped or negative range that breaks theboolean[]allocation. Promote the subtraction tolongbefore 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] == 1for every adjacent pair is enough; no min/max scan orseenarray is needed. - What if duplicates are allowed as long as the distinct values are consecutive? – load the values into a
HashSet<Integer>first, then compareset.size()tomax - min + 1instead 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 frommintomaxsignals 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
mintomax; 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.



