03
Missing + duplicate together (Cyclic Sort Sub-pattern)
One value appears twice and one is missing. After placement there is exactly one wrong slot, and it gives both answers: the duplicate is the value in it, and the missing number is its index + 1.
Signals in the problem statement
- ›
"one number was duplicated and one was lost"
- ›
"return [repeated, missing]"
- ›
the same thing on an n × n grid holding 1..n²
What makes it different
It's the same placement, just read differently. Watch the order of the output ([duplicate, missing]). For a grid, map value v to cell ((v − 1) / n, (v − 1) % n). If the array were read-only, the math way (sum and sum of squares) also works, but it needs long long.
Questions
ordered from “learn the idea” to “recognise it without help”- 1Set MismatchWalkthroughEasyBasic Anchor·LeetCode #645
- 2Find Missing and Repeated ValuesWalkthroughEasyBasic Reinforcement·LeetCode #2965
- 3Find Missing and RepeatingWalkthroughMediumMedium·GeeksforGeeks
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?