NeetCode #54LC-448EasyArrays & Hashing
← Back to All Problems#54 · #448 · Find All Numbers Disappeared in an Array(找到所有数组中消失的数字)
📌 Problem Statement & Constraints
Given an array
nums of n integers where each element is in the range [1, n], return an array of all the integers in [1, n] that do not appear in nums. Constraints: n == nums.length, 1 <= n <= 10^5. Solve it in O(n) time with O(1) auxiliary space (the output array does not count).💡 Core Algorithmic Approaches
- Because every value lies in
[1, n], the valuevcan serve as an index into the array itself:v - 1. - Marking pass: for each value, take the absolute value (it may already have been negated), then negate
nums[v - 1]to record thatvwas seen. - Collecting pass: any index
iwhose value is still positive meansi + 1was never marked, soi + 1is missing. - Using
abson the read is essential, because a previously negated slot would otherwise give a negative index.
💻 Benchmark Python3 Implementation
class Solution:
def findDisappearedNumbers(self, nums: List[int]) -> List[int]:
n = len(nums)
for i in range(n):
idx = abs(nums[i]) - 1 # abs is required: the slot may be negated
if nums[idx] > 0:
nums[idx] = -nums[idx] # mark as seen
res = []
for i in range(n):
if nums[i] > 0: # never marked -> i+1 is missing
res.append(i + 1)
return res
# Cyclic-sort variant: place each value at its home index first
class Solution2:
def findDisappearedNumbers(self, nums: List[int]) -> List[int]:
n = len(nums)
i = 0
while i < n:
home = nums[i] - 1
if nums[i] != nums[home]: # swap into the correct slot
nums[i], nums[home] = nums[home], nums[i]
else:
i += 1
return [i + 1 for i in range(n) if nums[i] != i + 1]⚡ Complexity Deep Dive
⏱️ Time Complexity
O(n): two passes, with O(1) amortised work per element. The cyclic-sort variant is also O(n) amortised, since each swap places one value permanently.
💾 Space Complexity
O(1) auxiliary: the input array is used as the marking structure. A hash-set solution would be O(n) space.
⚠️ Interview Pitfalls & Follow-ups
- Forgetting
absin the marking pass: once a slot is negated, reading it directly yields a negative index, which in Python silently wraps around and corrupts the marking. - Marking with
nums[idx] = -1unconditionally: it would still work for this problem, but negating is the safer idiom because it preserves the magnitude for the second pass. - Using a set: O(n) space, violating the stated O(1) requirement.
- Assuming the array is a permutation: it is not, which is exactly why some numbers are missing.