448. Find All Numbers Disappeared in An Array - Explanation
Description
You are given an array nums of n integers where nums[i] is in the range [1, n], return an array of all the integers in the range [1, n] that do not appear in nums.
Note: You can return the integers in any order.
Example 1:
Input: nums = [4,3,2,7,8,2,3,1]
Output: [5,6]Example 2:
Input: nums = [1,1]
Output: [2]Constraints:
1 <= nums[i] <= nums.length <= 100,000
Follow up: Could you do it without extra space and in O(n) runtime? You may assume the returned list does not count as extra space.
Topics
Prerequisites
Before attempting this problem, you should be comfortable with:
- Hash Sets - Used to efficiently track which numbers are present in the array
- Array Index Manipulation - Understanding how values in range [1, n] map to array indices [0, n-1]
- In-Place Array Modification (Negative Marking) - The optimal solution modifies the input array to mark visited indices
1. Hash Set
Intuition
We need to find numbers in the range [1, n] that are missing from the array. A simple approach is to create a set containing all numbers from 1 to n, then remove each number we find in the array. Whatever remains in the set are the missing numbers.
Algorithm
- Create a set containing all integers from
1ton. - For each number in the input array, remove it from the set.
- Return the remaining elements in the set as a list.
Time & Space Complexity
- Time complexity:
- Space complexity:
2. Boolean Array
Intuition
Instead of using a set, we can use a boolean array where mark[i] indicates whether the number i+1 is present in the input. We first mark all numbers that appear, then collect all indices where the mark is still false.
Algorithm
- Create a boolean array
markof sizen, initialized tofalse. - For each number in the input array, set
mark[num - 1] = true. - Iterate through indices
1ton:- If
mark[i - 1]isfalse, addito the result.
- If
- Return the result list.
Time & Space Complexity
- Time complexity:
- Space complexity:
3. Sorting
Intuition
After sorting, we can use a two-pointer technique to find missing numbers. We iterate through numbers 1 to n and use a pointer to track our position in the sorted array. If the current number is not found at the pointer position, it must be missing.
Algorithm
- Sort the array.
- Initialize a pointer
idx = 0. - For each number from
1ton:- Move
idxforward whilenums[idx] < num(skip duplicates and smaller values). - If
idxreaches the end ornums[idx] > num, the number is missing; add it to the result.
- Move
- Return the result list.
Time & Space Complexity
- Time complexity:
- Space complexity: or depending on the sorting algorithm.
4. Negative Marking
Intuition
Since values are in range [1, n], we can use the input array itself as a marker. For each value v, we mark the position v-1 as visited by making it negative. After processing all values, any position that remains positive corresponds to a missing number.
Algorithm
- For each number in the array:
- Compute the index as
abs(num) - 1. - Make
nums[idx]negative (use absolute value to handle already-negated elements).
- Compute the index as
- Iterate through the array:
- If
nums[i] > 0, the numberi + 1is missing; add it to the result.
- If
- Return the result list.
Time & Space Complexity
- Time complexity:
- Space complexity: since we modified the input array without using extra space.
Common Pitfalls
Confusing Indices and Values
Since values are in the range [1, n] but indices are [0, n-1], it is easy to mix them up. When marking position i as visited, remember that value v maps to index v-1. Similarly, when checking which numbers are missing, index i corresponds to the number i+1.
Double-Negating Already Marked Values
When using negative marking, if you negate a value that is already negative, it becomes positive again and appears as if that position was never visited. Always use abs() before negating to ensure the value becomes negative regardless of its current sign.
Sign in to join the discussion