Advertisement
Home Data Structure Arrays Find the Mode of an Array

Find the Mode of an Array

0
Advertisement

Title: Find the Mode of an Array

In this guide, you will learn how to find the mode of an array in Java. The mode is the value that appears the most times in a dataset, and it is a staple building block for frequency counting, voting algorithms, and histograms.

We will frame the problem, write a full Java program using a HashMap, trace it on a concrete input, and then look at the tie-breaking rule, the overflow-free count arithmetic, and the follow-up questions a Java interviewer tends to ask on this problem.

Understanding the Problem

Given an array of n integers, the mode is the element that appears with the highest frequency. For [4, 2, 4, 3, 2, 4, 5] the mode is 4 because it appears three times while every other value appears once or twice.

The definition leaves one decision to the implementer: if two or more values are tied for the highest frequency, which one do we return? For this guide we return the first value to reach the maximum count during a single left-to-right pass. This rule is simple, deterministic, and easy to defend in an interview.

Approach / Algorithm Steps

  1. Reject the input early if the array is null or empty, since the mode is undefined when there are no values.
  2. Create a HashMap from element value to running count, so each unique value is counted in O(1) amortised time.
  3. Initialise mode to numbers[0] and maxCount to 0 so the very first iteration will update both variables.
  4. Iterate once over the array. For each value, bump its count in the map and compare the new count to maxCount.
  5. If the new count is strictly greater than maxCount, update both maxCount and mode. The strict comparison implements the “first value to reach the max wins” tie-break rule.
  6. Return mode after the loop ends.

Java Program

Java
import java.util.HashMap;
import java.util.Map;

public class ArrayMode {
    public static int findMode(int[] numbers) {
        if (numbers == null || numbers.length == 0) {
            throw new IllegalArgumentException("Array must not be null or empty");
        }
        Map<Integer, Integer> counts = new HashMap<>();
        int mode = numbers[0];
        int maxCount = 0;
        for (int value : numbers) {
            int count = counts.getOrDefault(value, 0) + 1;
            counts.put(value, count);
            if (count > maxCount) {
                maxCount = count;
                mode = value;
            }
        }
        return mode;
    }

    public static void main(String[] args) {
        int[] values = {4, 2, 4, 3, 2, 4, 5};
        int mode = findMode(values);
        System.out.println("Mode: " + mode);
    }
}

Explanation of the Program

The class ArrayMode exposes a single static method, findMode, which takes an int[] and returns an int. Returning a primitive int is appropriate here because the mode is always one of the elements in the input array, never a derived fractional value.

The method starts by rejecting null or empty input with an IllegalArgumentException. There is no meaningful default to return for the mode of nothing, so pushing the error back to the caller is the honest choice.

The frequency table is a Map<Integer, Integer> created with the diamond operator new HashMap<>(). Autoboxing turns each int value into an Integer key, which is the price we pay for using a generic map; for most inputs the amortised O(1) lookup more than makes up for it.

The loop uses the enhanced for syntax for (int value : numbers) so the index does not appear anywhere. On every iteration counts.getOrDefault(value, 0) + 1 reads the current count (defaulting to 0 for a value seen for the first time) and increments it, then counts.put(value, count) stores the new count back.

The comparison count > maxCount uses a strict greater-than, not >=. That is the key tie-break choice: when a new value matches but does not exceed maxCount, the current mode keeps its lead. Only a value that overtakes the leader replaces it, so the first value to reach each new maximum wins.

The main method shows a tiny driver: it builds a sample array where 4 appears three times and every other value appears once or twice, calls findMode, and prints the result. Running it prints Mode: 4.

Step-by-Step Trace

Let us trace findMode on the input [6, 2, 6, 1, 2, 6]. The expected mode is 6 because it appears three times, more than any other value.

Stepvaluecount (after bump)count > maxCount?maxCount (after)mode (after)
161yes16
221no16
362yes26
411no26
522no26
663yes36

At the end of each iteration, mode holds the first value to have reached the current maxCount. Step 5 is the one that demonstrates the strict comparison: 2 ties the leading count of 2 but does not overtake it, so mode stays at 6.

Examples

Example 1: Clear single mode

One value dominates with a strictly higher count than every other value in the array.

Java
int[] nums = {1, 2, 2, 3, 4};
int mode = findMode(nums);
System.out.println(mode);
// Counts: {1:1, 2:2, 3:1, 4:1}
// Output: 2

Example 2: Tied frequencies, first-reached wins

Two values tie for the top count. The strict > comparison keeps the first one to reach that count as the mode.

Java
int[] nums = {5, 7, 5, 7};
int mode = findMode(nums);
System.out.println(mode);
// Counts: {5:2, 7:2}
// Output: 5

Example 3: Single-element array

A one-element array has exactly one value with frequency 1, so that value is the mode.

Java
int[] nums = {42};
int mode = findMode(nums);
System.out.println(mode);
// Counts: {42:1}
// Output: 42

Common Mistakes to Avoid

The algorithm is short, but the tie-break rule and Java’s boxing semantics produce several reliable traps. These are the mistakes learners actually make on this problem.

  • Using >= instead of > – every tied value overwrites mode, so the result silently flips to whichever tied value appears last. Keep the comparison strictly count > maxCount if you want “first to reach the max” semantics.
  • Initialising maxCount to numbers[0]‘s frequency – this skips the update for the first element, so the loop never records that numbers[0] was in fact seen once. Initialise maxCount = 0 instead and let the first iteration do the first update.
  • Returning maxCount instead of mode – the method is asked for the value that appears most often, not for how often it appears. Watch the two variables carefully in the final return.
  • Confusing Integer equality – if you ever compare boxed Integer values with == instead of .equals, two Integer instances outside the cache range (-128 to 127) will compare unequal even when their int values match. Prefer primitive int for the loop variables.
  • Not handling the empty array – without the up-front check, numbers[0] throws ArrayIndexOutOfBoundsException and the error message tells the caller nothing about the real problem. Throw IllegalArgumentException with a descriptive message instead.

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 ask about.

  • Empty array
  • Null array reference
  • Single-element array
  • All identical elements
  • All distinct elements (every value is tied at frequency 1)
  • Two or more values tied at the maximum frequency
  • Negative values alongside positive values
  • Integer.MIN_VALUE and Integer.MAX_VALUE present

Additional Considerations

The HashMap-based solution runs in O(n) average time, since every element costs one lookup and one update, each amortised O(1). The extra space is O(k) where k is the number of distinct values; in the worst case that is O(n), when every value is unique.

The alternative is to sort the array first and then scan for the longest run of equal values. That approach runs in O(n log n) time but needs only O(1) extra space if the sort is in-place, and it also lets you walk the counts in sorted order, which is sometimes useful downstream.

The Integer.MIN_VALUE / Integer.MAX_VALUE edge case is worth a sanity check. The count itself can never overflow because the count is bounded by numbers.length, which fits in an int. The hash code of boxed Integer values is well-defined across the entire int range, so no special handling is required.

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.

  • How would you return every mode when more than one value is tied for the highest count? – make a two-pass solution: first build the frequency map, then collect into a list every value whose count equals the maximum.
  • How would you return the k most frequent elements? – feed the (value, count) pairs into a min-heap of size k, giving O(n log k) overall time.
  • How would you find the majority element (one that appears strictly more than n / 2 times) in O(1) extra space? – use the Boyer-Moore voting algorithm, which maintains a single candidate and a running count across one pass.
  • How would you find the mode of a stream too large to fit in memory? – use an approximate frequent-items sketch such as Misra-Gries or Count-Min, trading a bounded error for sub-linear memory.
  • How would you find the mode of a sorted array in O(1) extra space? – scan the array once, counting the length of each run of equal values and tracking the longest run so far, which is the mode.

Conclusion

Finding the mode of an array in Java is a one-pass loop built around a HashMap, with two decisions tucked inside it: initialise maxCount to 0 so the first iteration can do the first update, and use a strict > comparison so that ties keep the earliest leader. Once those two habits are in place, the same shape of code extends cleanly to top-k queries, streaming, and majority voting.

Try adapting the code above to return every tied mode as an int[], and compare its output on arrays where every element is unique against the single-value version. The two approaches agree only when there is a unique winner.

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