💡 Swapping places the current element closer to its correct position.
compare
After swap, check again at i=2
After swapping, nums[2] is still 2 and nums[correct] is nums[1] = 2. Since they are equal, no swap occurs and i increments.
💡 If swapping does not change the element at i, it means a duplicate is detected and we move forward.
Line:if nums[i] != nums[correct]:
# swap
else:
i += 1
💡 Duplicate elements cause the algorithm to move forward without infinite swapping.
compare
Check if nums[i] is at correct position
At i=3, nums[3] = 4. The correct position for 4 is index 3. Since nums[3] == nums[3], no swap needed.
💡 The last element is in the correct position, so we move i forward.
Line:correct = nums[i] - 1
if nums[i] != nums[correct]:
# swap
else:
i += 1
💡 The algorithm has finished the cyclic sort loop as i reaches n.
traverse
Start scanning to find mismatch
Now we iterate over the array from i=0 to find the first index where nums[i] != i + 1.
💡 This scan identifies the duplicate and missing numbers by detecting the mismatch.
Line:for i in range(n):
if nums[i] != i + 1:
return [nums[i], i + 1]
💡 Mismatch between value and index+1 reveals the duplicate and missing pair.
compare
Check if nums[0] == 1
At i=0, nums[0] = 1 which equals i + 1 = 1, so continue scanning.
💡 Matching value means no error at this index.
Line:if nums[i] != i + 1:
return [nums[i], i + 1]
💡 Correctly placed elements are skipped.
compare
Check if nums[1] == 2
At i=1, nums[1] = 2 which equals i + 1 = 2, so continue scanning.
💡 Still no mismatch, continue scanning.
Line:if nums[i] != i + 1:
return [nums[i], i + 1]
💡 Elements in correct position are confirmed.
compare
Detect mismatch at i=2
At i=2, nums[2] = 2 but i + 1 = 3, so mismatch found. Duplicate is 2, missing is 3.
💡 Mismatch reveals the duplicate and missing numbers directly.
Line:if nums[i] != i + 1:
return [nums[i], i + 1]
💡 Mismatch between value and expected index+1 identifies the error pair.
def findErrorNums(nums):
i = 0 # STEP 1
n = len(nums)
while i < n: # STEP 2-6
correct = nums[i] - 1 # STEP 2
if nums[i] != nums[correct]: # STEP 4
nums[i], nums[correct] = nums[correct], nums[i] # STEP 4
else:
i += 1 # STEP 2,3,5,6
for i in range(n): # STEP 7-10
if nums[i] != i + 1: # STEP 8-10
return [nums[i], i + 1] # STEP 10
return [-1, -1]
📊
Set Mismatch (One Duplicate, One Missing) - Watch the Algorithm Execute, Step by Step
Watching each swap and pointer move reveals how cyclic sort efficiently places numbers and how the mismatch reveals the duplicate and missing values.
Step 1/10
·Active fill★Answer cell
compare
i
1
0
2
1
2
2
4
3
Result: "[]"
move_right
1
0
i
2
1
2
2
4
3
Result: "[]"
move_right
1
0
2
1
i
2
2
4
3
Result: "[]"
swap
1
0
2
1
i
2
2
4
3
Result: "[]"
move_right
1
0
2
1
2
2
i
4
3
Result: "[]"
move_right
1
0
2
1
2
2
4
3
Result: "[]"
compare
i
1
0
2
1
2
2
4
3
Result: "[]"
move_right
1
0
i
2
1
2
2
4
3
Result: "[]"
move_right
1
0
2
1
i
2
2
4
3
Result: "[]"
record
1
0
2
1
i
2
2
4
3
Result: "[2, 3]"
Key Takeaways
✓ Cyclic sort places each number at its correct index, making it easy to spot duplicates and missing numbers by scanning once.
This insight is hard to see from code alone because the swapping logic and pointer increments are subtle without visualization.
✓ When a duplicate is encountered, the algorithm avoids infinite swaps by moving the pointer forward, ensuring termination.
Understanding this prevents confusion about why the algorithm doesn't get stuck swapping duplicates endlessly.
✓ The mismatch between the value and its index+1 after sorting directly reveals the duplicate and missing numbers.
This concrete example shows how the final scan leverages the sorted array structure to find the answer efficiently.
Practice
(1/5)
1. You are given an array of integers where each integer is between 1 and n (inclusive), and some elements appear twice while others appear once. Which algorithmic approach guarantees finding all duplicate elements in O(n) time and O(1) extra space?
easy
A. Cyclic sort to place each number at its correct index, then scanning for mismatches
B. Using a hash set to track seen elements and identify duplicates
C. Sorting the array and then scanning for consecutive duplicates
D. Applying a dynamic programming approach to count occurrences
Solution
Step 1: Understand problem constraints
The array contains numbers from 1 to n, allowing index-based placement.
Step 2: Identify approach that uses in-place swaps
Cyclic sort places each number at index = number - 1, enabling O(n) time and O(1) space.
Final Answer:
Option A -> Option A
Quick Check:
Cyclic sort exploits value-index mapping for optimal duplicate detection [OK]
Hint: Use cyclic sort for O(n) time and O(1) space [OK]
Common Mistakes:
Assuming sorting is always O(n) time
Believing hash sets use O(1) space
Confusing DP applicability for duplicates
2. Given the following code snippet implementing the cyclic sort approach, what is the returned output when the input array is [2, 2, 3]?
easy
A. [2, 1]
B. [2, 1]
C. [2, 1]
D. [2, 1]
Solution
Step 1: Trace the cyclic sort swaps
Initial array: [2, 2, 3]. i=0, nums[0]=2, correct_index=1. nums[0] == nums[1], so increment i to 1. i=1, nums[1]=2, correct_index=1, same index, increment i to 2. i=2, nums[2]=3, correct_index=2, correct place, increment i to 3.
Step 2: Identify mismatch in final array
Final array remains [2, 2, 3]. Check indices: i=0 expects 1 but has 2 (duplicate), i=1 expects 2 and has 2 (correct), i=2 expects 3 and has 3 (correct). The mismatch at i=0 means duplicate=2, missing=1.
Final Answer:
Option B -> Option B
Quick Check:
Output matches expected corrupt pair [2, 1] [OK]
Hint: Trace swaps carefully; duplicates cause no swap but increment index [OK]
Common Mistakes:
Off-by-one in indexing
Returning wrong pair order
Missing increment after swap
3. Consider the following Python function that finds the first k missing positive numbers using cyclic sort and a boolean array. What is the output of find_k_missing_numbers([3, -1, 4, 5, 5], 3)?
After sorting, the array becomes [1, -1, 3, 4, 5] with 1 at index 0, -1 at index 1, 3 at index 2, 4 at index 3, and 5 at index 4. Negative numbers are ignored in placement.
Step 2: Identify missing numbers and extras
Missing numbers are 2 (since index 1 != 2), and since k=3, the next missing number beyond array length is 6. So missing = [1, 2, 6].
Final Answer:
Option D -> Option D
Quick Check:
Output matches expected missing positives [OK]
Hint: Cyclic sort places numbers correctly; missing are indices not matching values [OK]
Common Mistakes:
Confusing indices and values after cyclic sort
Forgetting to add missing numbers beyond array length
Miscounting duplicates as missing
4. What is the time complexity of the optimal cyclic sort approach to find all duplicates in an array of size n, and why might some candidates mistakenly think it is higher?
medium
A. O(n^2) because nested swaps can happen repeatedly
B. O(n log n) because of the sorting-like swaps
C. O(n) because each element is swapped at most once to its correct position
D. O(n) but with O(n) extra space for tracking duplicates
Solution
Step 1: Analyze the while loop behavior
Each swap places at least one element in its correct position, so total swaps ≤ n.
Step 2: Understand why time is linear
Since each element is moved at most once, total operations are O(n).
Final Answer:
Option C -> Option C
Quick Check:
Swapping each element once ensures linear time [OK]
Hint: Each element moves at most once -> O(n) time [OK]
Common Mistakes:
Assuming swaps cause O(n^2) due to nested loops
Confusing cyclic sort with comparison-based sorting
Forgetting that extra space is O(1)
5. Suppose the problem is modified so that the input array can contain duplicates and the missing positive range must consider repeated numbers as well (e.g., if 2 appears twice, the missing range should still be correct). Which modification to the cyclic sort approach correctly handles duplicates without causing infinite loops or incorrect missing ranges?
hard
A. Skip swapping when nums[i] == nums[correct_pos] to avoid infinite loops caused by duplicates
B. Use a hash set to track visited numbers during cyclic sort swaps
C. Sort the array first to group duplicates, then apply cyclic sort
D. Increment i unconditionally after every swap regardless of duplicates
Solution
Step 1: Understand duplicate handling in cyclic sort
Duplicates cause infinite swapping if we swap identical numbers repeatedly.
Step 2: Modify swap condition
Adding a check to skip swapping when nums[i] == nums[correct_pos] prevents infinite loops and preserves correctness.
Step 3: Confirm other options fail
Hash sets add extra space, sorting breaks O(n) time, unconditional increment after swap may skip needed swaps.
Final Answer:
Option A -> Option A
Quick Check:
Skipping swaps on duplicates is standard fix for cyclic sort with duplicates [OK]
Hint: Avoid swapping identical elements to handle duplicates safely [OK]
Common Mistakes:
Ignoring duplicates causing infinite loops
Adding extra space unnecessarily
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.