Advertisement
Home Data Structure Arrays Check if Two Arrays are Equal Ignoring Order

Check if Two Arrays are Equal Ignoring Order

1
Advertisement

Title: Check if Two Arrays are Equal Ignoring Order

In this guide, you’ll learn how to check whether two arrays contain the same elements with the same frequency, regardless of the order in which they appear. This is a classic interview warm-up that tests whether you reach for a shortcut like sorting or a frequency map, and whether you handle duplicate values correctly.

We’ll build a Java program using a HashMap to count occurrences, trace it step by step on a fresh input, and then walk through the edge cases and follow-up questions an interviewer is likely to ask.

Understanding the Problem

Given two integer arrays, arr1 and arr2, we want to determine if they are equal when order does not matter. Two arrays are equal ignoring order only if every value appears the exact same number of times in both arrays. Simply checking that both arrays contain the same distinct values is not enough; {2, 2, 3} and {2, 3, 3} share the same distinct values but are not equal ignoring order, because the value 2 appears a different number of times in each.

The naive approach of nested loops to find a match for every element works but costs O(n^2) time. A better approach tracks how many times each value occurs using a HashMap, giving a linear time solution.

Approach

Here is the step-by-step approach we will implement:

  1. Compare the lengths of arr1 and arr2. If they differ, the arrays cannot be equal, so return false immediately.
  2. Create a HashMap<Integer, Integer> called frequency to record how many times each value occurs.
  3. Iterate over arr1 and increment the count for each value in frequency, using getOrDefault to handle new keys safely.
  4. Iterate over arr2. For each value, look up its count in frequency.
  5. If the value is missing from frequency, or its count is already zero, the arrays are not equal, so return false immediately.
  6. Otherwise, decrement the count for that value in frequency and continue.
  7. If the loop over arr2 completes without returning false, the arrays are equal ignoring order, so return true.

Java Program

Here is the complete, compilable Java program:

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

public class EqualArraysIgnoringOrder {

    public static boolean areEqualIgnoringOrder(int[] arr1, int[] arr2) {
        if (arr1.length != arr2.length) {
            return false;
        }

        Map<Integer, Integer> frequency = new HashMap<>();

        for (int value : arr1) {
            frequency.put(value, frequency.getOrDefault(value, 0) + 1);
        }

        for (int value : arr2) {
            Integer count = frequency.get(value);
            if (count == null || count == 0) {
                return false;
            }
            frequency.put(value, count - 1);
        }

        return true;
    }

    public static void main(String[] args) {
        int[] arr1 = {4, 2, 7, 2, 9};
        int[] arr2 = {9, 2, 4, 2, 7};

        boolean result = areEqualIgnoringOrder(arr1, arr2);
        System.out.println("Arrays equal ignoring order: " + result);
    }
}

Explanation of the Program

The method areEqualIgnoringOrder first checks the array lengths; mismatched lengths short-circuit the rest of the logic before any counting happens.

The first loop builds a frequency table from arr1, using getOrDefault so a value seen for the first time starts at 0 before being incremented.

The second loop walks arr2 and spends its count against the table built from arr1. Any value that is missing, or whose count has already reached zero, proves the arrays are not equal, and the method returns immediately.

If every value in arr2 finds a matching, unspent count in the frequency table, the arrays contain the same elements the same number of times, just in a different order.

Step-by-Step Trace

Let’s trace the algorithm on arr1 = {6, 1, 6, 9} and arr2 = {1, 6, 9, 9}. After the first loop, frequency holds {6: 2, 1: 1, 9: 1}. The second loop then proceeds as follows:

Iterationarr2[i]count beforecount > 0?count after / action
111yesdecrement to 0
262yesdecrement to 1
391yesdecrement to 0
490noreturn false

At the end of each successful iteration, frequency holds the remaining unmatched count of every value seen in arr1; hitting a count of zero again means arr2 contains more occurrences of that value than arr1 does, so the arrays are not equal.

Examples

Example 1: Equal Arrays in a Different Order

arr1 and arr2 hold the same four values, just shuffled.

Java
int[] arr1 = {10, 20, 30, 40};
int[] arr2 = {40, 10, 30, 20};
// areEqualIgnoringOrder(arr1, arr2) returns true

Example 2: Same Distinct Values, Different Counts

Both arrays contain only the values 5 and 7, but 5 appears twice in arr1 and only once in arr2.

Java
int[] arr1 = {5, 5, 7};
int[] arr2 = {5, 7, 7};
// areEqualIgnoringOrder(arr1, arr2) returns false

Example 3: Different Lengths

arr2 has an extra element, so the length check rejects it before any counting happens.

Java
int[] arr1 = {1, 2, 3};
int[] arr2 = {1, 2, 3, 3};
// areEqualIgnoringOrder(arr1, arr2) returns false

Common Mistakes to Avoid

These are the mistakes candidates most often make when solving this problem:

  • Comparing arrays with == or .equals() – both compare object references for arrays, not contents, so two arrays with identical elements are reported as unequal. Use a frequency map, or Arrays.equals after sorting, instead.
  • Collapsing duplicates into a Set – converting both arrays to sets before comparing makes {2, 2, 3} look equal to {2, 3, 3}, even though the counts differ. Track counts with a map, not just membership.
  • Skipping the length check – starting the comparison logic before confirming the arrays are the same size wastes work and can mask a mismatch that a single length check would catch instantly. Compare lengths first.
  • Calling get() without a default – writing frequency.get(value) + 1 throws a NullPointerException the first time a value is seen, because get() returns null for a missing key. Use getOrDefault(value, 0) instead.
  • Only checking containsKey() on the second pass – checking that a value exists in the map without decrementing its count lets extra duplicates in arr2 slip through undetected. Decrement the count and verify it is greater than zero before accepting a match.

Edge Cases to Test

Walk through these inputs before calling the solution complete:

  • Empty arrays
  • Arrays of different lengths
  • Single-element arrays
  • All identical elements
  • Duplicate elements with different counts
  • Negative numbers present
  • Null array reference
  • Large arrays with many repeated values

Additional Considerations

The HashMap approach runs in O(n) time and uses O(n) extra space for the frequency table, where n is the length of the arrays.

An alternative is to sort both arrays with Arrays.sort and compare them with Arrays.equals. This runs in O(n log n) time but needs no auxiliary map; the trade-off is that sorting mutates the original arrays unless you copy them first, and it is slower asymptotically than counting.

Choose the frequency map when the arrays must stay unmodified and speed matters most. Choose sorting when memory is tight and a small constant-factor slowdown is acceptable.

Interview Follow-up Questions

An interviewer will often extend the base problem with questions like these:

  • What if the arrays hold String values instead of int? – the same frequency-map approach works unchanged; swap the array type and the map’s key type to String.
  • What if you cannot use any extra memory? – sort both arrays in place with Arrays.sort and compare them element by element, trading O(n) space for O(n log n) time.
  • What if the arrays are too large to fit in memory? – sort each array externally with a merge-based external sort, then stream both sorted arrays from disk and compare them one block at a time.
  • What if you need to report which values differ, not just a boolean? – keep the frequency map after the second loop and return every key whose count is not zero.
  • What if order should be ignored but duplicate counts should not matter at all? – convert both arrays to Set<Integer> and compare their sizes along with containsAll.

Conclusion

Checking whether two arrays are equal ignoring order comes down to counting, not just membership. A HashMap that tracks how many times each value occurs catches the duplicate-count mismatches that a naive set comparison would miss, all in linear time.

Try adapting the areEqualIgnoringOrder method to work with String or double arrays, or to return the differing elements instead of a simple boolean. You can learn more about array-based interview problems in our Arrays category.