2Brute2Best
🔥0
01

Missing number (Cyclic Sort Sub-pattern)

Put every value that exists at its home. The slots left without their own value are the missing numbers.

Signals in the problem statement
  • ›

    "find the missing number" in 0..n

  • ›

    "find all numbers that disappeared" from 1..n

  • ›

    "smallest missing positive" with O(1) space

What makes it different

The difference is which values have no home. In 0..n (LC 268) the home of v is v and the value n gets parked. With duplicates (LC 448) a twin gets stuck in a hole and every hole is a missing number. In First Missing Positive anything ≤ 0 or > n is ignored and you return the first hole (or n + 1).

Questions

ordered from “learn the idea” to “recognise it without help”
  1. 1
    Missing Number
    Basic Anchor·LeetCode #268
    Easy
  2. 2
    Find All Numbers Disappeared in an Array
    Basic Reinforcement·LeetCode #448
    Easy
  3. 3
    First Missing Positive
    Tricky / Edge Case·LeetCode #41
    Hard

Template

place-template.cpp
// Values 1..n (duplicates allowed): put each value at its home index v - 1,
// then every slot that doesn't hold its own value tells you something.
void placeAll(vector<int>& nums) {
    int n = nums.size();
    for (int i = 0; i < n; i++) {
        // keep swapping at i until the value here can't move anywhere useful
        while (nums[nums[i] - 1] != nums[i]) {       // NOT nums[i] != i + 1 (loops on duplicates)
            swap(nums[i], nums[nums[i] - 1]);        // one more value is home for good
        }
    }
}

// After placeAll: slot i holds i + 1, or it holds a squatter.
void readLeftovers(const vector<int>& nums, vector<int>& missing, vector<int>& duplicates) {
    for (int i = 0; i < (int)nums.size(); i++) {
        if (nums[i] != i + 1) {
            missing.push_back(i + 1);                // nobody brought value i + 1
            duplicates.push_back(nums[i]);           // its twin already owns its home
        }
    }
}
Remember this · Cyclic Sort
Trigger
Numbers in range 1..n or 0..n, find missing / duplicate / both, O(1) extra space.
Think
Can value v live at index v−1? Then put everyone home and look for squatters.
Key question
Where does value v belong, and when do I stop swapping?