Advertisement
Home Data Structure Arrays Count Negative Numbers in an Array

Count Negative Numbers in an Array

3
Advertisement

Title: Count Negative Numbers in an Array

In this guide, you will learn how to count the negative numbers in an array using Java. The problem is a one-pass loop with a single strict comparison, and it is the mirror of the “count positives” problem with one shared pitfall: zero is neither positive nor negative.

We will walk through the problem, build a complete program, trace it on a sample input, and then look at the < versus <= trap, the arithmetic-shift sign-bit alternative, and the follow-up questions a Java interviewer tends to ask on this problem.

Understanding the Problem

Given an array of n integers, the task is to return how many of them are negative. A number is negative when it is strictly less than 0. For the input [-3, 5, -1, 0, 4, -8, 2], the negative values are -3, -1, and -8, so the answer is 3.

The entire problem hinges on one definition. In mathematics, “negative” means strictly less than zero; “non-positive” means less than or equal to zero. Writing value <= 0 instead of value < 0 counts non-positives, which includes 0. If the problem asked for the count of non-positives, that would be the right check, but it does not.

Approach / Algorithm Steps

  1. Reject the input early if the array is null, since the count is undefined for a missing reference. An empty array is fine: its count is 0.
  2. Declare a counter count initialised to 0.
  3. Walk the array with an enhanced for loop so no index is tracked.
  4. For each element value, test whether value < 0. The strict comparison excludes 0, which is neither positive nor negative.
  5. Increment count for every matching element and return it once the loop ends.

Java Program

Java
public class CountNegatives {
    public static int countNegatives(int[] numbers) {
        if (numbers == null) {
            throw new IllegalArgumentException("Array must not be null");
        }
        int count = 0;
        for (int value : numbers) {
            if (value < 0) {
                count++;
            }
        }
        return count;
    }

    public static void main(String[] args) {
        int[] values = {-3, 5, -1, 0, 4, -8, 2};
        int negatives = countNegatives(values);
        System.out.println("Negative count: " + negatives);
    }
}

Explanation of the Program

The class CountNegatives exposes a single static method, countNegatives, which takes an int[] and returns a plain int. The result cannot exceed numbers.length, which already fits in an int, so no wider return type is needed.

The method validates only against null, not against an empty array. The count of negatives in an empty array is a perfectly well-defined 0, so throwing there would punish a reasonable caller. Rejecting null is still worth doing because an unchecked dereference would surface as a NullPointerException on the for line, which gives the caller no useful information about what went wrong.

The loop uses the enhanced for syntax for (int value : numbers) so no index is tracked. For a problem that does not care about position, dropping the index removes a whole class of off-by-one mistakes.

The test value < 0 is the heart of the method, and the choice of operator is deliberate. Writing value <= 0 would count 0, but 0 is neither positive nor negative. The strict < excludes 0 on the one hand and every positive value on the other, so only strictly negative values survive the comparison.

When the test passes, count++ increments the running total. The ++ postfix operator is the idiomatic way to bump a counter by 1, and it is a touch clearer here than count += 1.

The main method is a tiny driver: it builds a sample array that mixes negatives, positives, and a 0, calls countNegatives, and prints the result. Running it prints Negative count: 3, which correctly excludes the 0.

Step-by-Step Trace

Let us trace countNegatives on the input [-2, 4, -7, 0, -5, 1]. The expected final answer is 3, since the negative values are -2, -7, and -5.

Iterationvaluevalue < 0?count (before)count (after)
1-2yes01
24no11
3-7yes12
40no22
5-5yes23
61no33

At the end of iteration i, count holds the number of negative values among numbers[0..i-1]. Step 4 is the one that demonstrates the strict comparison: 0 fails the < 0 check and the counter stays put, exactly as the definition of “negative” requires.

Examples

Example 1: Mixed positive and negative values

A straightforward input where positives and negatives alternate. Only the strictly negative values are counted.

Java
int[] nums = {-6, 3, -2, 1, -4};
int negatives = countNegatives(nums);
System.out.println(negatives);
// Negatives: -6, -2, -4
// Output: 3

Example 2: Non-negatives (positives and a zero)

No element is strictly less than zero, so the count stays at 0. This example also pins down that 0 itself is excluded.

Java
int[] nums = {0, 1, 2, 3};
int negatives = countNegatives(nums);
System.out.println(negatives);
// Output: 0

Example 3: All negative values

Every element passes the strict comparison, so the count equals the array length.

Java
int[] nums = {-1, -2, -3, -4};
int negatives = countNegatives(nums);
System.out.println(negatives);
// Output: 4

Common Mistakes to Avoid

The algorithm looks like a one-liner, but the definition of “negative” and a tempting unsigned-shift lookalike together produce several reliable traps. These are the mistakes learners actually make on this problem.

  • Using value <= 0 – silently counts 0 as negative, which does not match the mathematical definition. For [0, 0, 0] the count comes out as 3 instead of 0. Use the strict value < 0 instead.
  • Using value < 1 – the sneaky integer-only restatement of value <= 0, so it has the same bug for every int input. Stick with the direct value < 0.
  • Using !(value > 0) – the double-negative restatement of value <= 0, also with the same bug and harder to read. Prefer the direct comparison.
  • Using (value >>> 31) == 1 on the wrong side – the unsigned right shift puts the sign bit into the low bit, so the expression is true exactly for strictly negative values and does work, but learners often confuse it with (value >>> 31) == 0, which is the non-negative check. Pick the right side carefully if you reach for the bitwise form.
  • Returning early on the first non-negative value – placing a return inside an else branch exits the method as soon as any zero or positive appears, so the count is almost always wrong. Only return count; after the loop completes.

Edge Cases to Test

Walk through this checklist before you call the solution done. The first few are the ones an interviewer is most likely to probe.

  • Empty array (count is 0)
  • Null array reference
  • Single-element array (negative, zero, or positive)
  • All elements negative
  • All elements positive
  • All elements zero
  • Mix of negative, positive, and zero values
  • Integer.MIN_VALUE (negative, counted) and Integer.MAX_VALUE (positive, excluded)

Additional Considerations

The algorithm runs in O(n) time, since every element is visited exactly once, and there is no way to do better for an unordered array because any element can tip the count. The space complexity is O(1), because only the counter and the loop variable are allocated regardless of the input size.

If the array is sorted in non-decreasing order, the problem collapses to a binary search. The negatives form a contiguous prefix of the array, so finding the smallest index k whose value is at least 0 gives a count of k directly in O(log n) time. The linear scan still runs in the same time or worse, so sort-aware callers should prefer the binary search.

A valid bitwise alternative to value < 0 is (value >> 31) != 0. The arithmetic right shift sign-extends, so a negative value becomes all-ones (-1) and a non-negative value becomes 0. The non-zero check then selects exactly the negative values. On modern JVMs the compiler already lowers both expressions to the same machine code, so the choice is purely about readability.

Interview Follow-up Questions

The base problem is only the opening move. A real interviewer will push with questions like these, each probing a different axis of the solution.

  • Can you count negatives, positives, and zeros together in one pass? – keep three counters inside the same loop; the time stays O(n) and the space stays O(1).
  • How would you count negatives in a sorted array? – binary-search for the smallest index whose value is at least 0; the count is exactly that index, which runs in O(log n) time.
  • How would you count negatives in a 2D matrix sorted non-increasingly in both rows and columns? – walk a staircase from the bottom-left corner: move up when the current cell is non-negative, move right (adding the remaining row width to the count) when it is negative, giving O(m + n) total.
  • How would you partition the array into negatives, zeros, and positives in-place? – use the Dutch National Flag algorithm with three pointers, which classifies every element in a single O(n) pass and O(1) extra space.
  • How would you count negatives in a very large array in parallel? – use Arrays.stream(numbers).parallel().filter(v -> v < 0).count(), which splits the array into chunks, counts each chunk independently, and sums the chunk counts.

Conclusion

Counting the negative numbers in an array in Java is a one-pass loop built around a single strict comparison, with two decisions tucked inside it: validate against null but accept an empty array (whose count is a perfectly honest 0), and use value < 0 rather than value <= 0 so 0 is correctly excluded. Once those two habits are in place, the same shape of code generalises to sorted-input binary search, staircase search over a 2D matrix, Dutch-flag partitioning, and parallel reduce at scale.

Try adapting the code above to return the three-way split (negatives, zeros, positives) rather than just the negative count. The whole method becomes a tiny sign-histogram over the array in a single pass.

You can learn more Array problems like this one here: Arrays.