2Brute2Best
🔥0

Set Mismatch

Easy·LeetCode #645Basic Anchor
LeetCode
30-Second Mental ModelCyclic Sort (missing + duplicate together)
Complexity:O(N²)→O(N)
Key Insight

Give value v the home nums[v − 1] and swap every value home. Every value that exists reaches its home, except the second copy of the duplicate — its home is already taken. It gets left in the only free slot, which is the home of the missing value. So the one slot i with nums[i] != i + 1 holds the duplicate, and i + 1 is the missing value.

Core Validity Invariant

Keep swapping while nums[i] != nums[nums[i] − 1] (the home of nums[i] does not already hold it). Afterwards, the only i with nums[i] != i + 1 gives duplicate = nums[i] and missing = i + 1.

01

Problem

An array nums of length n was supposed to hold every number from 1 to n exactly once. By mistake, one number got copied over another one. So now one value appears twice and one value is missing.

Return both of them as [duplicate, missing] — the repeated value first, then the missing value.

Input

An integer array nums of length n, with values in 1..n.

Output

An array of two numbers: [duplicate, missing].

Example 1
Input: nums = [1, 2, 2, 4]
Output: [2, 3]

2 shows up twice and 3 never shows up.

Example 2
Input: nums = [1, 1]
Output: [1, 2]

1 is repeated, so 2 is missing.

Constraints
  • • 2 ≤ nums.length ≤ 10^4
  • • 1 ≤ nums[i] ≤ 10^4
  • • Exactly one value is repeated and exactly one value in 1..n is missing.
02

First, think yourself

Before opening any solution, try to answer these on paper. Use hints only when stuck — each hint is counted.

  1. 1.

    The values should be exactly 1..n. How many of them can I check directly, one by one?

  2. 2.

    If I could use extra memory, what would tell me "how many times does k appear?" quickly?

  3. 3.

    The array has n slots and the values are 1..n. Is there a natural slot for each value?

  4. 4.

    If every value moves into its own slot, what would the slot of the missing value end up holding?

  5. 5.

    The answer wants two numbers. Which one comes first?

03

Brute force approach

04

Better approach

05

Optimized approach

06

Why does this algorithm work?

07

Dry run

08

All approaches compared

ApproachIdeaTimeSpace
Brute ForceFor each k in 1..n, scan the array and count how often k appearsO(N²)O(1)
BetterCount every value once in an array of size n + 1O(N)O(N)
OptimalSwap each value v into index v − 1; the one wrong slot gives both answersO(N)O(1)
09

Why does this belong to this pattern?

Clues in the problem statement
  • “numbers 1 to n”Each value v has a natural home: index v − 1.
  • “one number repeated”One value finds its home already occupied by its twin.
  • “one number missing”One home never receives its owner.
  • “return both”The same wrong slot shows both: the value in it is the duplicate, its index + 1 is the missing value.
Values 1..n in n slots+one duplicate+one missing→Cyclic Sort (missing + duplicate together)

In the missing sub-pattern we only read the index of the wrong slot. In the duplicate sub-pattern we only read the value in it. Here the two meet: one value appears twice and one is missing, so the single wrong slot gives both — its value is the duplicate and its index + 1 is the missing number.

10

Don't make this mistake

Returning the answer in the wrong order
✗ return {i + 1, nums[i]}; // [missing, duplicate]
✓ return {nums[i], i + 1}; // [duplicate, missing]

This is the pattern-confusion trap. In the missing sub-pattern the index (i + 1) is the answer, so it is easy to put it first. Here the problem wants the duplicate first. On [1, 2, 2, 4] the wrong order returns [3, 2] instead of [2, 3].

Infinite loop: checking the slot instead of the home
✗ while (nums[i] != i + 1) swap(nums[i], nums[nums[i] - 1]);
✓ while (nums[i] != nums[nums[i] - 1]) swap(nums[i], nums[nums[i] - 1]);

This condition works when every value is distinct, but here one value is doubled. On [1, 1], at i = 1 the value 1 is not at index 1, so it is swapped with index 0 — which also holds 1. Nothing changes and the loop never ends. Asking "does the home already hold this value?" stops the duplicate.

Using if instead of while
✗ if (nums[i] != nums[nums[i] - 1]) swap(nums[i], nums[nums[i] - 1]);
✓ while (nums[i] != nums[nums[i] - 1]) swap(nums[i], nums[nums[i] - 1]);

After one swap, the value that lands at i may also need to move. With if, it can stay out of place. On [4, 3, 2, 7, 8, 2, 6, 1] the if version ends as [7, 2, 3, 4, 1, 6, 2, 8] with three wrong slots, and returns [7, 1] instead of [2, 5].

Finding the duplicate with a set but guessing the missing value
✗ // found dup with a set, then: missing = dup + 1;
✓ // after placement: if (nums[i] != i + 1) return {nums[i], i + 1};

The missing value has nothing to do with the duplicate's value. In [3, 2, 3, 4, 6, 5] the duplicate is 3 and the missing value is 1.

11

Want to implement this?

Write it yourself on LeetCode, then come back and compare your code with the solutions above.

Open coding workspace
How did it go?
Beyond The LeetCode Problem

How this concept connects to System Design & C++ Systems

Bridge DSA with production engineering

Top engineering interviews test whether you understand how algorithms like Cyclic Sort translate into production architectures and low-level memory mechanics.