Title: Find the Repeating and the Missing Number
The repeating-and-missing problem is a favorite array question in Java interviews because it forces you to reason about two broken invariants at once. You are given an array that should contain every integer from 1 to N exactly once, but one value has been duplicated and another value is missing entirely. In this guide, you’ll learn a clean counting-based approach, see the full Java program, trace it on a concrete input, and work through the edge cases and follow-up questions interviewers like to ask.
By the end of this tutorial, you’ll understand why a frequency array makes both numbers fall out of a single pass, how the approach generalizes, and when an arithmetic trick can replace the extra memory it uses.
Understanding the Problem
You are given an array numbers of size N whose values are supposed to be the integers 1 through N, each appearing exactly once. Because of a data error, one value appears twice and a different value is missing, so the array still has N elements overall.
For example, if the input is:
int[] numbers = {4, 3, 6, 2, 1, 1};Then 1 is the repeating number and 5 is the missing number, because 1 appears twice and 5 never appears among the six slots that should hold 1 through 6.
A brute-force solution would compare every pair of elements, costing O(n^2) time. Sorting first brings that down to O(n log n). The counting approach below solves it in a single linear pass.
Approach: Frequency Counting
Since every valid value is bounded between 1 and N, we can allocate a count array of size N + 1 and use each value as a direct index. Walking the input once lets us spot the repeating number the moment its count reaches 2. A second short pass over count finds the one index that was never touched, which is the missing number.
Here are the steps:
- Read
n = numbers.lengthand allocatecount = new int[n + 1]. - Iterate over
numbers, incrementingcount[numbers[i]]on every element. - The instant any
count[numbers[i]]reaches2, recordnumbers[i]as therepeatingvalue. - After the first loop, scan indices
1throughnofcount. - The first index whose
countis still0is themissingvalue. - Return both values together, for example as a two-element array.
Java Program to Find the Repeating and the Missing Number
Here is the complete, runnable Java program that implements the counting approach:
public class FindRepeatingAndMissingNumber {
public static int[] findRepeatingAndMissing(int[] numbers) {
int n = numbers.length;
int[] count = new int[n + 1];
int repeating = -1;
for (int i = 0; i < n; i++) {
count[numbers[i]]++;
if (count[numbers[i]] == 2) {
repeating = numbers[i];
}
}
int missing = -1;
for (int i = 1; i <= n; i++) {
if (count[i] == 0) {
missing = i;
break;
}
}
return new int[] {repeating, missing};
}
public static void main(String[] args) {
int[] numbers = {4, 3, 6, 2, 1, 1};
int[] result = findRepeatingAndMissing(numbers);
System.out.println("Repeating number: " + result[0]);
System.out.println("Missing number: " + result[1]);
}
}Explanation of the Program
- The method
findRepeatingAndMissingaccepts the arraynumbersand returns a two-element array holding the repeating value at index0and the missing value at index1. - The
countarray is sizedn + 1so that values from1toncan be used directly as indices without any offset arithmetic. - During the first
forloop,count[numbers[i]]++records how many times each value has been seen. The checkcount[numbers[i]] == 2fires exactly once, the moment the duplicate shows up. - The second
forloop never touches the original array again; it only inspectscountto find the single index that stayed at0. - The
breakstatement stops the second loop as soon asmissingis found, since there is only ever one missing value to look for. - The
mainmethod builds a sample array, callsfindRepeatingAndMissing, and prints both results.
Step-by-Step Trace
Let’s trace the algorithm on the input numbers = [3, 1, 2, 5, 3, 6], where n = 6. We expect 3 to come back as the repeating number and 4 as the missing number. Each row below shows one iteration of the first for loop.
| Iteration | numbers[i] | count[numbers[i]] (before) | count[numbers[i]] (after) | repeating (after) |
|---|---|---|---|---|
| 1 | 3 | 0 | 1 | -1 |
| 2 | 1 | 0 | 1 | -1 |
| 3 | 2 | 0 | 1 | -1 |
| 4 | 5 | 0 | 1 | -1 |
| 5 | 3 | 1 | 2 | 3 |
| 6 | 6 | 0 | 1 | 3 |
After the loop finishes, the second pass scans count[1] through count[6] and finds count[4] == 0, so missing = 4. The invariant is that at the end of the first loop, count[v] holds exactly how many times value v appeared in numbers, and repeating holds the value whose count first reached 2.
Examples
Let’s look at a few concrete runs to see how the repeating value and the missing value can land at different positions in the range.
Example 1: Repeating Value at the Start
The value 1 occupies two of the five slots, so 2 never gets filled in.
int[] numbers = {1, 1, 3, 4, 5};
int[] result = findRepeatingAndMissing(numbers);
System.out.println("Repeating: " + result[0] + ", Missing: " + result[1]);
// Output: Repeating: 1, Missing: 2Example 2: Missing Value at the Start
Here 1 is the one that never appears, while 5 fills two slots instead of one.
int[] numbers = {2, 3, 4, 5, 5};
int[] result = findRepeatingAndMissing(numbers);
System.out.println("Repeating: " + result[0] + ", Missing: " + result[1]);
// Output: Repeating: 5, Missing: 1Example 3: Repeating and Missing in the Middle
Both broken values sit in the interior of the range, which is the most common shape you’ll see in practice.
int[] numbers = {1, 2, 2, 4, 5, 6};
int[] result = findRepeatingAndMissing(numbers);
System.out.println("Repeating: " + result[0] + ", Missing: " + result[1]);
// Output: Repeating: 2, Missing: 3Common Mistakes to Avoid
This problem looks simple, but a few subtle slips show up again and again. Watch out for these:
- Sizing count as new int[n] – using
numbers[i]as an index into an array of sizenthrowsArrayIndexOutOfBoundsExceptionwhen a value equalsn. Allocatecountwith sizen + 1so every value from1tonhas a slot. - Overwriting repeating on every match – checking
count[numbers[i]] >= 2instead of== 2reassignsrepeatingevery time the duplicate is seen again later, which is harmless here but signals a misunderstanding of the invariant. Check for exact equality to2so the assignment happens only once. - Scanning for missing starting at index 0 –
count[0]is always0because no valid value is ever0, so starting the second loop ati = 0incorrectly reports0as missing. Start the scan ati = 1. - Assuming the repeating and missing values are adjacent – some learners hardcode logic that expects the two broken values to be close together. They can be anywhere in the range, including at opposite ends, so the scan must check every index independently.
- Forgetting that exactly one value is missing and one is duplicated – if the input can have more than one duplicate or more than one missing value, this single-pass count approach only reports one of each; you would need to collect every index whose count is
0or2instead of stopping at the first match.
Edge Cases to Test
Before you call the solution complete, run it through these inputs. They cover the boundaries interviewers probe for:
- Repeating value equals
1(the first integer) - Missing value equals
n(the last integer) - Repeating value equals
nand missing value equals1at the same time - Smallest valid input:
n = 2with one value duplicated - Repeating and missing values adjacent to each other
- Array already sorted versus fully shuffled
- Null array reference
- Array whose length does not match the claimed range of values
Additional Considerations
The counting approach runs in O(n) time because it makes exactly two linear passes, one over numbers and one over count. It uses O(n) auxiliary memory for the count array, which is the trade-off worth remembering.
If an interviewer asks for O(1) extra space, switch to the sum-and-sum-of-squares trick: let x be the repeating value and y be the missing value. The difference between the actual sum and the expected sum n * (n + 1) / 2 equals x - y, and the difference between the actual sum of squares and the expected sum of squares equals x^2 - y^2. Dividing the second difference by the first gives x + y, and from x - y and x + y you can solve for both values directly. Use long accumulators, since the sum of squares grows quickly.
Both techniques assume exactly one repeating value and exactly one missing value within the range 1 to n. If that guarantee does not hold, validate the input before trusting either formula.
Interview Follow-up Questions
Once the base version works, expect an interviewer to push further with questions like these:
- Can you solve it with O(1) extra space? – use the sum and sum-of-squares identities instead of a count array; both sums can be computed in a single pass with
longaccumulators. - What if there are two repeating values and two missing values instead of one each? – a single count array still works, but you must collect every index with count
0or count2rather than stopping at the first match, so drop the earlybreak. - What if the array must remain read-only and cannot be modified? – the counting approach never mutates
numbers, so it already satisfies a read-only constraint; only an in-place marking trick, such as negating visited indices, would violate it. - What if the input arrives as a stream and n is not known in advance? – track a running sum, running sum of squares, and a running count of elements seen; once the stream ends, treat the final count as
nand apply the arithmetic approach. - What if the array is too large to fit in memory? – process it in chunks while maintaining running sum and sum-of-squares accumulators across chunks; since both identities are associative, the final answer does not depend on how the chunks were split.
Conclusion
Finding the repeating and the missing number comes down to tracking how many times each valid value shows up. A frequency array makes both broken values fall out of a single linear pass, and the sum-based identities give you a constant-space alternative when memory is tight. Together they cover the two answers interviewers expect you to know for this problem.
Try extending the program to report multiple repeating or missing values, or rewrite it using the sum-and-sum-of-squares trick to compare the two approaches side by side. Working through both versions will make the trade-off between time, space, and code clarity much more concrete.
You can learn more about array algorithms here: Arrays.



