🧠
Optimal Cyclic Sort In-Place
💡 This approach uses the cyclic sort pattern to place each number at its correct index, enabling identification of missing numbers without extra space.
Intuition
Since numbers are from 1 to n, each number should be at index number-1. By swapping numbers to their correct positions, misplaced indices reveal missing numbers.
Algorithm
- Initialize index i to 0.
- While i < n, if nums[i] is not at its correct position and the target position does not already have the correct number, swap nums[i] with nums[nums[i]-1].
- Else, increment i.
- After sorting, traverse the array to collect indices where nums[i] != i + 1; these indices + 1 are missing numbers.
- Return the collected missing numbers.
💡 This algorithm rearranges the array in-place to reveal missing numbers by mismatches, avoiding extra space.
def findDisappearedNumbers(nums):
i = 0
n = len(nums)
while i < n:
correct = nums[i] - 1
if nums[i] != nums[correct]:
nums[i], nums[correct] = nums[correct], nums[i]
else:
i += 1
missing = []
for i in range(n):
if nums[i] != i + 1:
missing.append(i + 1)
return missing
# Driver code
if __name__ == '__main__':
print(findDisappearedNumbers([4,3,2,7,8,2,3,1])) # Output: [5,6]
Line Notes
i = 0Start index at 0 to begin cyclic sort.
n = len(nums)Store length for loop bounds.
while i < n:Loop through array to place numbers correctly.
correct = nums[i] - 1Calculate correct index for current number.
if nums[i] != nums[correct]:Check if current number is misplaced and target position is different.
nums[i], nums[correct] = nums[correct], nums[i]Swap to place number at correct index.
else:If number is at correct position or duplicate, move forward.
i += 1Increment index to continue scanning.
missing = []Prepare list to collect missing numbers.
for i in range(n):Traverse array to find mismatches.
if nums[i] != i + 1:Mismatch indicates missing number at this index.
missing.append(i + 1)Add missing number to result.
import java.util.*;
public class Solution {
public static List<Integer> findDisappearedNumbers(int[] nums) {
int i = 0, n = nums.length;
while (i < n) {
int correct = nums[i] - 1;
if (nums[i] != nums[correct]) {
int temp = nums[i];
nums[i] = nums[correct];
nums[correct] = temp;
} else {
i++;
}
}
List<Integer> missing = new ArrayList<>();
for (i = 0; i < n; i++) {
if (nums[i] != i + 1) {
missing.add(i + 1);
}
}
return missing;
}
public static void main(String[] args) {
System.out.println(findDisappearedNumbers(new int[]{4,3,2,7,8,2,3,1})); // Output: [5, 6]
}
}
Line Notes
int i = 0, n = nums.length;Initialize index and store array length.
while (i < n)Loop to place numbers at correct indices.
int correct = nums[i] - 1;Calculate correct index for current number.
if (nums[i] != nums[correct])Check if current number is misplaced and target position differs.
int temp = nums[i]; nums[i] = nums[correct]; nums[correct] = temp;Swap numbers to correct position.
else { i++; }If number is correct or duplicate, move to next index.
List<Integer> missing = new ArrayList<>();Prepare list to collect missing numbers.
for (i = 0; i < n; i++)Traverse array to find mismatches.
if (nums[i] != i + 1)Mismatch indicates missing number.
missing.add(i + 1);Add missing number to result list.
#include <iostream>
#include <vector>
using namespace std;
vector<int> findDisappearedNumbers(vector<int>& nums) {
int i = 0, n = nums.size();
while (i < n) {
int correct = nums[i] - 1;
if (nums[i] != nums[correct]) {
swap(nums[i], nums[correct]);
} else {
i++;
}
}
vector<int> missing;
for (int i = 0; i < n; i++) {
if (nums[i] != i + 1) {
missing.push_back(i + 1);
}
}
return missing;
}
int main() {
vector<int> nums = {4,3,2,7,8,2,3,1};
vector<int> result = findDisappearedNumbers(nums);
for (int num : result) cout << num << " "; // Output: 5 6
cout << endl;
return 0;
}
Line Notes
int i = 0, n = nums.size();Initialize index and store vector size.
while (i < n)Loop to place numbers at correct indices.
int correct = nums[i] - 1;Calculate correct index for current number.
if (nums[i] != nums[correct])Check if current number is misplaced and target differs.
swap(nums[i], nums[correct]);Swap numbers to correct positions.
else { i++; }If number is correct or duplicate, move forward.
vector<int> missing;Prepare vector to collect missing numbers.
for (int i = 0; i < n; i++)Traverse vector to find mismatches.
if (nums[i] != i + 1)Mismatch indicates missing number.
missing.push_back(i + 1);Add missing number to result vector.
function findDisappearedNumbers(nums) {
let i = 0, n = nums.length;
while (i < n) {
let correct = nums[i] - 1;
if (nums[i] !== nums[correct]) {
[nums[i], nums[correct]] = [nums[correct], nums[i]];
} else {
i++;
}
}
const missing = [];
for (let i = 0; i < n; i++) {
if (nums[i] !== i + 1) {
missing.push(i + 1);
}
}
return missing;
}
// Test
console.log(findDisappearedNumbers([4,3,2,7,8,2,3,1])); // Output: [5,6]
Line Notes
let i = 0, n = nums.length;Initialize index and store array length.
while (i < n)Loop to place numbers at correct indices.
let correct = nums[i] - 1;Calculate correct index for current number.
if (nums[i] !== nums[correct])Check if current number is misplaced and target differs.
[nums[i], nums[correct]] = [nums[correct], nums[i]];Swap numbers to correct positions.
else { i++; }If number is correct or duplicate, move forward.
const missing = [];Initialize array to collect missing numbers.
for (let i = 0; i < n; i++)Traverse array to find mismatches.
if (nums[i] !== i + 1)Mismatch indicates missing number.
missing.push(i + 1);Add missing number to result array.
Each number is swapped at most once to its correct position, so total operations are linear. No extra space is used except output.
💡 For n=100,000, this means roughly 100,000 operations, which is very efficient.
Interview Verdict: Accepted and optimal
This is the best approach for this problem, combining efficiency and minimal space.