Find the First Non-Consecutive Number in Java


The challenge

Your task is to find the first element of an array that is not consecutive.

By not consecutive we mean not exactly 1 larger than the previous element of the array.

E.g. If we have an array [1,2,3,4,6,7,8] then 1 then 2 then 3 then 4 are all consecutive but 6 is not, so that’s the first non-consecutive number.

If the whole array is consecutive then return null.

The array will always have at least 2 elements1 and all elements will be numbers. The numbers will also all be unique and in ascending order. The numbers could be positive or negative and the first non-consecutive could be either too!

Can you write a solution that will return null for both [] and [ x ] though? (This is an empty array and one with a single number and is not tested for, but you can write your own example test. )

The solution in Java code

In our solution, we loop through all elements of the array, except for the last element. Each time checking if the next element’s value is 1 more than the current element.

If it is not, then we return the next element’s value.

If all else fails, and we complete our loop, then we return null.

class FirstNonConsecutive {
    static Integer find(final int[] array) {
        
        for (int i=0; i<array.length-1; i++) {
            if (array[i+1]!=array[i]+1)
              return array[i+1];
        }
      
        return null;
    }
}

We could also come to a similar solution by using the IntStream functionality, as follows:

import java.util.stream.*;

class FirstNonConsecutive {
    static Integer find(final int[] array) {
      return IntStream.range(1, array.length).filter(i -> array[i-1] != array[i]-1)
                     .mapToObj(x -> new Integer(array[x])).findFirst().orElse(null);
    }
}

Test cases to validate our Java code

import org.junit.Test;
import static org.junit.Assert.assertEquals;

public final class FirstNonConsecutiveTest {
    @Test public void basicTests() {
        assertEquals(Integer.valueOf(6), FirstNonConsecutive.find(new int[]{1, 2, 3, 4, 6, 7, 8}));
        assertEquals(null, FirstNonConsecutive.find(new int[]{1, 2, 3, 4, 5, 6, 7, 8}));
        assertEquals(Integer.valueOf(6), FirstNonConsecutive.find(new int[]{4, 6, 7, 8, 9, 11}));
        assertEquals(Integer.valueOf(11), FirstNonConsecutive.find(new int[]{4, 5, 6, 7, 8, 9, 11}));
        assertEquals(null, FirstNonConsecutive.find(new int[]{31, 32}));
        assertEquals(Integer.valueOf(0), FirstNonConsecutive.find(new int[]{-3, -2, 0, 1}));
        assertEquals(Integer.valueOf(-1), FirstNonConsecutive.find(new int[]{-5, -4, -3, -1}));
    }
}

Extended test cases

import java.util.Arrays;
import java.util.Random;
import java.util.Set;
import java.util.HashSet;
import org.junit.Test;
import static org.junit.Assert.assertEquals;

public final class FirstNonConsecutiveTest {
    @Test public void basicTests() {
        assertEquals(Integer.valueOf(6), FirstNonConsecutive.find(new int[]{1, 2, 3, 4, 6, 7, 8}));
        assertEquals(null, FirstNonConsecutive.find(new int[]{1, 2, 3, 4, 5, 6, 7, 8}));
        assertEquals(Integer.valueOf(6), FirstNonConsecutive.find(new int[]{4, 6, 7, 8, 9, 11}));
        assertEquals(Integer.valueOf(11), FirstNonConsecutive.find(new int[]{4, 5, 6, 7, 8, 9, 11}));
        assertEquals(null, FirstNonConsecutive.find(new int[]{31, 32}));
        assertEquals(Integer.valueOf(0), FirstNonConsecutive.find(new int[]{-3, -2, 0, 1}));
        assertEquals(Integer.valueOf(-1), FirstNonConsecutive.find(new int[]{-5, -4, -3, -1}));
    }

    @Test public void randomTests() {
        Random random = new Random();
        for (int i = 0; i < 20; i++) {
            int length = random.nextInt(15) + 1;
            int[] array = new int[length];
            int start = random.nextInt(10000) - (10000/4); //25% should start less than zero
            for (int j=0; j<length; j++) {
              array[j] = start;
              start++;
              if (random.nextInt(100) > 90) start++;
            }
            assertEquals("For input \"" + Arrays.toString(array) + '"', kata(array), FirstNonConsecutive.find(array));
        }
    }

    private static Integer kata(final int[] array) {
        for (int i = 1; i < array.length; i++) {
            if (array[i] != array[i - 1] + 1) {
                return array[i];
            }
        }
        return null;
    }
}