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”- 1Missing NumberWalkthroughEasyBasic Anchor·LeetCode #268
- 2Find All Numbers Disappeared in an ArrayWalkthroughEasyBasic Reinforcement·LeetCode #448
- 3First Missing PositiveWalkthroughHardTricky / Edge Case·LeetCode #41
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?