2
\$\begingroup\$

Write a method isConsecutive that accepts an ArrayList of integers as a parameter and returns true if the list contains a sequence of consecutive integers and false otherwise. Consecutive integers are integers that come one after the other in ascending order, as in 5, 6, 7, 8, 9, etc. For example, if a variable called list stores the values [3, 4, 5, 6, 7, 8, 9], then the call of list.isConsecutive() should return true. If the list instead stored [3, 4, 5, 6, 7, 12, 13] then the call should return false because the numbers 7 and 12 are not consecutive. The list [3, 2, 1] might seem to be consecutive, but the elements appear in reverse order, so the method would return false in that case. Any list with fewer than two values should be considered to be consecutive. You may assume that the list passed is not null.

Wondering which better ways there are to do this, and how to improve my future code.

public boolean isConsecutive(ArrayList<Integer> list) {
    int count = 0;
    for (int i = 0; i < list.size() - 1; i++) {
        if (list.get(i) == (list.get(i + 1) - 1)) {
            count++;
        } else {
            count = 0;
        }
    }
    return list.size() - 1 == count || list.isEmpty();
}
\$\endgroup\$

1 Answer 1

5
\$\begingroup\$

You don't need a counter in your code:

public boolean isConsecutive(ArrayList<Integer> list) {
    for (int i = 0; i < list.size() - 1; i++) {
        if (list.get(i) != list.get(i + 1) - 1) {
            return false;
        }
    }
    return true;
}

As a next step, you can change the loop to start at 1 instead of 0, so that the loop condition becomes simpler.

public boolean isConsecutive(ArrayList<Integer> list) {
    for (int i = 1; i < list.size(); i++) {
        if (list.get(i - 1) + 1 != list.get(i)) {
            return false;
        }
    }
    return true;
}

The specification does not require the algorithm to be constant-time (it's not used for cryptography), therefore it should be OK to return as soon as you know the answer.

To be extra correct, you could detect integer overflows:

int prev = list.get(i - 1);
if (prev != list.get(i) /* mismatch */ || prev + 1 < prev /* overflow */) {
    return false;
}

If the requirements were to change that you may only access each list element once, you would need to remember the previous value.

public boolean isConsecutive(ArrayList<Integer> list) {
    Iterator<Integer> it = list.iterator();
    if (!it.hasNext()) {
        return true;
    }

    int prev = it.next();
    while (it.hasNext()) {
        int curr = it.next();
        if (prev + 1 != curr /* mismatch */ || prev + 1 < prev /* overflow */) {
            return false;
        }
        prev = curr;
    }
    return true;
}
\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.