These clues point to Index as Hash (Cyclic Sort): When values are in the range 1..n, put each value at its own index (or mark that index) to find missing or duplicate numbers in O(1) space.
Stuck? Take one hint at a time
Solution.java · starter
class Solution {
public int missingNumber(int[] nums) {
return 0;
}
}
Write your solution locally or in your editor for now. The in-browser runner (Java first, then Python, C++ and more) will run these tests right here.
Put all values in a set, then check 0..n for the first one that's missing.
Approach 1
import java.util.HashSet;
import java.util.Set;
class Solution {
public int missingNumber(int[] nums) {
Set<Integer> seen = new HashSet<>();
for (int x : nums) seen.add(x);
for (int v = 0; v <= nums.length; v++) if (!seen.contains(v)) return v;
return -1;
}
}
Verdict: Works, but the range structure lets us do it without extra memory.
2
Index as hash (cyclic sort)
Time O(n) Space O(1)
Each value v in 0..n−1 belongs at index v. Swap values into their own index; the value n has no slot, so leave it. Afterwards, the first index i where nums[i] != i is the missing number. If every index matches, the missing number is n.
▶ Dry run: Sending each value homenums = [3, 0, 1]
3
0
↑i
0
1
1
2
Step 1/63 belongs at index 3, which doesn't exist (n = 3). Leave it and move on.
Approach 2
class Solution {
public int missingNumber(int[] nums) {
int n = nums.length, i = 0;
while (i < n) {
int v = nums[i];
if (v < n && v != nums[v]) { // v has a home slot and isn't there yet
nums[i] = nums[v];
nums[v] = v;
} else {
i++;
}
}
for (i = 0; i < n; i++) if (nums[i] != i) return i;
return n;
}
}
Verdict: No extra memory. The same idea solves harder problems like First Missing Positive.
3
Shortcut: expected sum minus actual sum
Time O(n) Space O(1)
0 + 1 + ... + n = n(n + 1) / 2. Subtract every element; what's left is the missing number. For large n the sum can overflow an int, so either use long or subtract as you go (missing += i + 1 - nums[i]), which keeps the running value small. XOR works the same way without overflow: XOR all indexes 0..n and all values, and pairs cancel.
Approach 3
class Solution {
public int missingNumber(int[] nums) {
int missing = 0;
for (int i = 0; i < nums.length; i++) {
missing += (i + 1) - nums[i]; // never grows beyond n, no overflow
}
return missing;
}
}
Verdict: The shortest answer. Mention the overflow issue to show care.
Before you submit
Edge cases and common mistakes
Test these inputs
Missing 0
Missing n (all indexes match)
n = 1
Mistakes people make
Computing n(n+1)/2 in an int for large n (overflow).
In cyclic sort, advancing i after every swap: the value swapped in may also need moving.
Forgetting that the value n has no slot and looping forever trying to place it.