The Aftermath

Let's look at what cyclic sort with the duplicate guard leaves behind. Start with [1, 3, 2, 3, 5] and run the full algorithm. You get:

1
const sorted = [1, 2, 3, 3, 5];
2
//    index:    0  1  2  3  4
3
//  expected:   1  2  3  4  5

Almost sorted. Index 0 holds 1 — correct. Index 1 holds 2 — correct. Index 2 holds 3 — correct. Index 4 holds 5 — correct. But index 3 holds 3 instead of 4. That's the imposter — the duplicate that couldn't be placed because its home was already occupied.

One position is wrong. But that single mismatch is hiding two pieces of information. What should be at index 3? The value 4 — that's the missing number. What is at index 3? The value 3 — that's the duplicate. The same mismatch tells you both who's absent and who showed up twice. Think of it like a seating chart at a dinner party: if seat 4 has the wrong guest, you instantly know which guest is missing (the one assigned to seat 4) and which guest is a gatecrasher (whoever is actually sitting there).

This duality is the engine behind an entire family of LeetCode problems. Let's see it in action.

Two Faces of a Mismatch

After cyclic sort with duplicates, the array looks almost right.
1
0
2
1
3
2
3
3
5
4

After cyclic sort, every value should equal its index + 1. Without checking each cell, what KIND of position would break this rule?

One Scan, Two Answers

After cyclic sort, one linear scan extracts everything you need:

1
for (let i = 0; i < n; i++) {
2
  if (nums[i] !== i + 1) {
3
    const missing = i + 1;      // what SHOULD be here
4
    const duplicate = nums[i];  // what IS here (the imposter)
5
  }
6
}

That's the whole pattern. The scan walks each index and asks one question: does this position hold its rightful owner? If yes, move on. If no, you've found a mismatch — and every mismatch has two faces. The expected value (i + 1) is missing from the array. The actual value (nums[i]) appears more times than it should.

Now watch how this single scan maps to four different LeetCode problems. LC 268 (Missing Number) asks “which value is absent?” — you return missing. LC 287 (Find the Duplicate Number) asks “which value appears twice?” — you return duplicate. LC 442 (Find All Duplicates) asks for every duplicate — you collect all duplicate values. LC 448 (Find All Numbers Disappeared) asks for every missing value — you collect all missing values. Same cyclic sort. Same scan. Same two-faced mismatch. The only thing that changes is which face you read and whether you collect one result or many.

Every undeliverable letter in the mailroom tells you both who's missing from the route and who sent a copy. You just need to know which question the problem is asking. Next: what happens when the mailbag includes junk?