The array should contain each number from 1 to n exactly once, but one number is duplicated and one is missing. The most direct approach is to count how many times each number from 1 to n appears in the array. A number appearing twice is the duplicate, and a number appearing zero times is the missing one.
[duplicate, missing].i from 1 to n:i appears in the array.0, i is the missing number.2, i is the duplicate number.After sorting, consecutive elements should differ by exactly 1. If two adjacent elements are equal, we found the duplicate. If two adjacent elements differ by 2, the missing number lies between them. We also need to handle the edge case where the missing number is n (the last element after sorting is not n).
missing = 1 (handles the case where 1 is missing).2, the missing number is in between.n, then n is the missing number.[duplicate, missing].class Solution:
def findErrorNums(self, nums: List[int]) -> List[int]:
res = [0, 1]
nums.sort()
for i in range(1, len(nums)):
if nums[i] == nums[i - 1]:
res[0] = nums[i]
elif nums[i] - nums[i - 1] == 2:
res[1] = nums[i] - 1
if nums[-1] != len(nums):
res[1] = len(nums)
return resUsing extra space, we can count occurrences in a single pass and then check each number's frequency. A frequency array of size n+1 lets us directly index by number value. The number with count 2 is the duplicate, and the number with count 0 is the missing one.
n+1 initialized to 0.1 to n:count[i] is 0, i is the missing number.count[i] is 2, i is the duplicate number.[duplicate, missing].We can use the input array itself as a hash table by marking visited indices. For each number, we negate the value at the corresponding index. If we try to negate an already negative value, we found the duplicate. After processing, any positive value indicates its index corresponds to the missing number.
index + 1 is the missing number.[duplicate, missing].Using sum formulas, we can set up equations to solve for the duplicate and missing numbers. Let the duplicate be d and the missing be m. The difference between actual sum and expected sum gives us d - m. The difference between actual sum of squares and expected sum of squares gives us d^2 - m^2 = (d+m)(d-m). With these two equations, we can solve for both values.
x = sum(nums) - sum(1 to n), which equals duplicate - missing.y = sum(nums^2) - sum(1^2 to n^2), which equals duplicate^2 - missing^2.y = (duplicate + missing) * x, we get duplicate + missing = y / x.missing = (y/x - x) / 2 and duplicate = missing + x.[duplicate, missing].class Solution:
def findErrorNums(self, nums: List[int]) -> List[int]:
N = len(nums)
x = 0 # duplicate - missing
y = 0 # duplicate^2 - missing^2
for i in range(1, N + 1):
x += nums[i - 1] - i
y += nums[i - 1]**2 - i**2
missing = (y - x**2) // (2 * x)
duplicate = missing + x
return [duplicate, missing]XOR has the property that a ^ a = 0. If we XOR all numbers in the array with all numbers from 1 to n, pairs cancel out, leaving us with duplicate ^ missing. To separate them, we find a bit where they differ (using the rightmost set bit), then partition all numbers into two groups based on that bit. XORing within each group isolates the duplicate and missing values.
1 to n. This gives duplicate ^ missing.1 to n) into two groups based on this bit.x and y.[duplicate, missing].class Solution:
def findErrorNums(self, nums: List[int]) -> List[int]:
N = len(nums)
# a ^ a = 0
# xorr = (1 ^ 2 ^ ... N) ^ (nums[0] ^ nums[1] ^ ... nums[N - 1])
# xorr = missing ^ duplicate
xorr = 0
for i in range(1, N + 1):
xorr ^= i
xorr ^= nums[i - 1]
# bit that is set in only one number among (duplicate, missing),
# will be set in (duplicate ^ missing)
# take rightMost set bit for simplicity
rightMostBit = xorr & ~(xorr - 1)
# divide numbers (from nums, from [1, N]) into two sets w.r.t the rightMostBit
# xorr the numbers of these sets independently
x = y = 0
for i in range(1, N + 1):
if i & rightMostBit:
x ^= i
else:
y ^= i
if nums[i - 1] & rightMostBit:
x ^= nums[i - 1]
else:
y ^= nums[i - 1]
# identify the duplicate number from x and y
for num in nums:
if num == x:
return [x, y]
return [y, x]The problem asks to return [duplicate, missing] in that specific order. Accidentally swapping the order and returning [missing, duplicate] produces wrong answers even when both numbers are correctly identified.
When using the sorting approach, special handling is needed if the missing number is 1 (the first element) or n (the last element). These boundary cases require explicit checks beyond just comparing adjacent elements.