Back to Arrays
Q6Question 6 of 109

Count how many times a given number appears in an array

Key Concepts
  • Walk the array once with a counter and increment it each time an element matches the target value.
  • There is no early exit because the target can appear multiple times anywhere in the array.
  • For money compare with compareTo returning zero, not equals, because equals also checks scale.
  • Time complexity is O(n) and space complexity is O(1) regardless of how many matches exist.
  • This pattern is the foundation for frequency counting, histogram building, and detecting recurring charges.
  • For sorted arrays, binary search can find the first and last occurrence in O(log n) to compute the count without a full scan.

Definition

Walk the array once with a counter, and add one to the counter every time an element matches the target.
  • Linear scan – visit every element because the target can appear anywhere, giving O(n) time.
  • Counter variable – a single int count tracks matches, giving O(1) extra space.
  • No early exit – unlike existence checks, counting requires inspecting every element.
  • Value equality – for BigDecimal use compareTo returning zero, not equals, because equals also checks scale.
  • Result – the counter holds the total number of occurrences when the loop ends.

Rajesh wants to know how many times exactly Rs.5000 was debited from his account SAV2001 this month, perhaps a recurring subscription. He reads each transaction in his passbook, and every time the amount is exactly Rs.5000 he makes a tally mark. At the end, the number of tally marks is the count.

Understanding the Concepts

What is the problem?

Given an array and a target value, count how many times the target appears. In a banking context, Rajesh wants to detect how many times a recurring Rs.5000 subscription was charged to his savings account SAV2001 at National Bank of India this month.

How does the algorithm work?

Start a counter at zero. Loop through every element and compare it with the target. If they match, increment the counter. There is no early exit because the same value can appear at any position.

JAVA
package com.bank.service;

import java.math.BigDecimal;

public class RecurringChargeDetector {

    public static int countOccurrences(BigDecimal[] amounts, BigDecimal target) {
        if (amounts == null) {
            throw new IllegalArgumentException("Amounts array cannot be null");
        }
        int count = 0;
        for (BigDecimal amount : amounts) {
            if (target.compareTo(amount) == 0) {
                count++;
            }
        }
        return count;
    }

    public static void main(String[] args) {
        BigDecimal[] transactions = {
            new BigDecimal("5000.00"),
            new BigDecimal("12500.00"),
            new BigDecimal("5000"),
            new BigDecimal("8700.50"),
            new BigDecimal("5000.00"),
            new BigDecimal("3200.00")
        };
        BigDecimal target = new BigDecimal("5000");
        int count = countOccurrences(transactions, target);
        System.out.println("Rs.5000 charged " + count + " times this month");
    }
}
TEXT
Rs.5000 charged 3 times this month

Why use compareTo instead of equals for BigDecimal?

BigDecimal's equals method checks both numeric value and scale. So new BigDecimal("5000") and new BigDecimal("5000.00") are NOT equal under equals because their scales differ (0 vs 2). Using compareTo returning zero treats both as the same amount, which is what a bank customer expects.

JAVA
BigDecimal a = new BigDecimal("5000");
BigDecimal b = new BigDecimal("5000.00");

System.out.println(a.equals(b));       // false (scale differs)
System.out.println(a.compareTo(b) == 0); // true (same numeric value)

Why is there no early exit?

Unlike an existence check that can stop at the first match, counting must inspect every element because the target might appear again later. The worst case and the best case are both O(n).

What is the time and space complexity?

  • Time: O(n) because every element is visited once.
  • Space: O(1) because only a single counter variable is used.

What about sorted arrays?

If the array is sorted, you can find the first occurrence with binary search and the last occurrence with another binary search, then compute the count as lastIndex - firstIndex + 1. This gives O(log n) time instead of O(n), which is a significant improvement for large arrays that are already sorted.

JAVA
// For a sorted array, binary search approach
// firstIndex = lower bound of target
// lastIndex  = upper bound of target
// count = lastIndex - firstIndex + 1

What are common mistakes?

The most common mistake is using equals instead of compareTo for BigDecimal, which misses matches where the scale differs. Another mistake is using == for object comparison, which compares references, not values.

JAVA
// Wrong: reference comparison
if (amounts[i] == target) { count++; } // compares memory addresses

// Wrong: equals checks scale
if (amounts[i].equals(target)) { count++; } // misses scale-different matches

// Correct: value comparison
if (amounts[i].compareTo(target) == 0) { count++; }

How does this extend to frequency counting?

Counting occurrences of a single value is the building block for frequency histograms. To count occurrences of every distinct value, you can use a HashMap where the key is the amount (normalized with stripTrailingZeros) and the value is the count. This takes one pass and O(k) space where k is the number of distinct values.

JAVA
import java.util.HashMap;
import java.util.Map;

Map<BigDecimal, Integer> frequency = new HashMap<>();
for (BigDecimal amount : amounts) {
    BigDecimal key = amount.stripTrailingZeros();
    frequency.merge(key, 1, Integer::sum);
}

What should a senior engineer know?

A senior engineer normalises BigDecimal keys with stripTrailingZeros() before putting them in a HashMap, because HashMap uses equals and hashCode internally, and two BigDecimal values with different scales have different hash codes even if they represent the same number. Without normalisation, the frequency map would treat Rs.5000 and Rs.5000.00 as separate entries.

Visual Overview

DIAGRAM
  target = 5000
  amounts[]:  5000.00  12500  5000  8700.50  5000.00  3200
                │
                ▼
  count = 0
  ┌──────────────────────────────────────────────┐
  │  5000.00 compareTo 5000 == 0?  YES → count=1 │
  │  12500   compareTo 5000 == 0?  NO             │
  │  5000    compareTo 5000 == 0?  YES → count=2 │
  │  8700.50 compareTo 5000 == 0?  NO             │
  │  5000.00 compareTo 5000 == 0?  YES → count=3 │
  │  3200    compareTo 5000 == 0?  NO             │
  └──────────────────────────────────────────────┘
  Result: count = 3

Key Takeaway

Counting how many times a value appears in an array is a straightforward linear scan with a counter. I start a counter at zero, loop through every element, and increment the counter each time the element matches the target. There is no early exit because the target can appear anywhere, so I must inspect every element.

In my banking project at National Bank of India, I used this to build a recurring charge detector. Rajesh wanted to know how many times exactly five thousand rupees was debited this month so he could spot a subscription he forgot about. I loop through his transaction amounts and tally each one that equals five thousand.

The important nuance here is how I compare money. I compare BigDecimal values using the compareTo method and check for a result of zero, rather than using the equals method. The reason is that five thousand written as plain five thousand and five thousand written with two decimal places are the same amount of money, but the equals method considers them different because their scale differs. By using compareTo I treat them as equal in value, which is exactly what the customer means.

Remember one sentence: walk every element, compare with compareTo for BigDecimal, and increment the counter on each match.

---

Share
Use ← → arrow keys to navigate