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:
- Compare the lengths of
arr1andarr2. If they differ, the arrays cannot be equal, so returnfalseimmediately. - Create a
HashMap<Integer, Integer>calledfrequencyto record how many times each value occurs. - Iterate over
arr1and increment the count for each value infrequency, usinggetOrDefaultto handle new keys safely. - Iterate over
arr2. For each value, look up its count infrequency. - If the value is missing from
frequency, or its count is already zero, the arrays are not equal, so returnfalseimmediately. - Otherwise, decrement the count for that value in
frequencyand continue. - If the loop over
arr2completes without returningfalse, the arrays are equal ignoring order, so returntrue.
Java Program
Here is the complete, compilable Java program:
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:
| Iteration | arr2[i] | count before | count > 0? | count after / action |
|---|---|---|---|---|
| 1 | 1 | 1 | yes | decrement to 0 |
| 2 | 6 | 2 | yes | decrement to 1 |
| 3 | 9 | 1 | yes | decrement to 0 |
| 4 | 9 | 0 | no | return 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.
int[] arr1 = {10, 20, 30, 40};
int[] arr2 = {40, 10, 30, 20};
// areEqualIgnoringOrder(arr1, arr2) returns trueExample 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.
int[] arr1 = {5, 5, 7};
int[] arr2 = {5, 7, 7};
// areEqualIgnoringOrder(arr1, arr2) returns falseExample 3: Different Lengths
arr2 has an extra element, so the length check rejects it before any counting happens.
int[] arr1 = {1, 2, 3};
int[] arr2 = {1, 2, 3, 3};
// areEqualIgnoringOrder(arr1, arr2) returns falseCommon 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, orArrays.equalsafter 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 – writingfrequency.get(value) + 1throws aNullPointerExceptionthe first time a value is seen, becauseget()returnsnullfor a missing key. UsegetOrDefault(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 inarr2slip 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
Stringvalues instead ofint? – the same frequency-map approach works unchanged; swap the array type and the map’s key type toString. - What if you cannot use any extra memory? – sort both arrays in place with
Arrays.sortand compare them element by element, tradingO(n)space forO(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 withcontainsAll.
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.



