🧠
Cyclic Sort (Optimal In-Place)
💡 This approach uses the cyclic sort pattern to place each number at its correct index. The duplicate is detected when a number is already at its correct position. It is optimal in time and space and does not require extra memory.
Intuition
Since numbers are from 1 to n, each number should be at index number-1. Swap elements to their correct positions until a duplicate is found.
Algorithm
- Initialize index i to 0.
- While i < length of array:
- If nums[i] is not at its correct position (nums[i] != nums[nums[i] - 1]), swap it with the element at its correct position.
- Else if nums[i] is equal to nums[nums[i] - 1] and i != nums[i] - 1, then nums[i] is the duplicate; return it.
- If no duplicate found in the loop, return -1.
💡 The swapping ensures each number is placed correctly; duplicate detection happens when a number is already in its correct place.
def findDuplicate(nums):
i = 0
while i < len(nums):
correct_index = nums[i] - 1
if nums[i] != nums[correct_index]:
nums[i], nums[correct_index] = nums[correct_index], nums[i]
else:
if i != correct_index:
return nums[i]
else:
i += 1
return -1
# Driver code
if __name__ == '__main__':
print(findDuplicate([3,1,3,4,2])) # Output: 3
Line Notes
i = 0Start scanning from the first index
while i < len(nums):Loop until all elements are processed
correct_index = nums[i] - 1Calculate the correct index for current number
if nums[i] != nums[correct_index]:If current number is not at correct position, swap
nums[i], nums[correct_index] = nums[correct_index], nums[i]Swap to place number at correct index
else:If number is at correct position
if i != correct_index:If duplicate found because number is already at correct index
return nums[i]Return the duplicate number
i += 1Move to next index if no swap or duplicate found
public class Solution {
public static int findDuplicate(int[] nums) {
int i = 0;
while (i < nums.length) {
int correctIndex = nums[i] - 1;
if (nums[i] != nums[correctIndex]) {
int temp = nums[i];
nums[i] = nums[correctIndex];
nums[correctIndex] = temp;
} else {
if (i != correctIndex) {
return nums[i];
} else {
i++;
}
}
}
return -1;
}
public static void main(String[] args) {
int[] nums = {3,1,3,4,2};
System.out.println(findDuplicate(nums)); // Output: 3
}
}
Line Notes
int i = 0;Initialize index to start scanning
while (i < nums.length) {Loop through array elements
int correctIndex = nums[i] - 1;Find correct index for current number
if (nums[i] != nums[correctIndex]) {If number not at correct position, swap
int temp = nums[i];Temporary variable for swapping
nums[i] = nums[correctIndex];Swap step 1
nums[correctIndex] = temp;Swap step 2
if (i != correctIndex) {Check if duplicate found
return nums[i];Return duplicate number
i++;Increment index if no swap or duplicate
#include <iostream>
#include <vector>
using namespace std;
int findDuplicate(vector<int>& nums) {
int i = 0;
while (i < (int)nums.size()) {
int correctIndex = nums[i] - 1;
if (nums[i] != nums[correctIndex]) {
swap(nums[i], nums[correctIndex]);
} else {
if (i != correctIndex) {
return nums[i];
} else {
i++;
}
}
}
return -1;
}
int main() {
vector<int> nums = {3,1,3,4,2};
cout << findDuplicate(nums) << endl; // Output: 3
return 0;
}
Line Notes
int i = 0;Start scanning from first index
while (i < (int)nums.size()) {Loop through all elements
int correctIndex = nums[i] - 1;Calculate correct index for current number
if (nums[i] != nums[correctIndex]) {If number not at correct position, swap
swap(nums[i], nums[correctIndex]);Swap elements to place number correctly
if (i != correctIndex) {Check if duplicate found
return nums[i];Return duplicate number
i++;Increment index if no swap or duplicate
function findDuplicate(nums) {
let i = 0;
while (i < nums.length) {
let correctIndex = nums[i] - 1;
if (nums[i] !== nums[correctIndex]) {
[nums[i], nums[correctIndex]] = [nums[correctIndex], nums[i]];
} else {
if (i !== correctIndex) {
return nums[i];
} else {
i++;
}
}
}
return -1;
}
// Test
console.log(findDuplicate([3,1,3,4,2])); // Output: 3
Line Notes
let i = 0;Initialize index to start scanning
while (i < nums.length) {Loop through array elements
let correctIndex = nums[i] - 1;Calculate correct index for current number
if (nums[i] !== nums[correctIndex]) {If number not at correct position, swap
[nums[i], nums[correctIndex]] = [nums[correctIndex], nums[i]];Swap elements using destructuring
if (i !== correctIndex) {Check if duplicate found
return nums[i];Return duplicate number
i++;Increment index if no swap or duplicate
Each element is swapped at most once to its correct position, resulting in linear time.
💡 For n=1000, this means about 1000 swaps or checks, which is very efficient.
Interview Verdict: Accepted and optimal
This approach is the best for this problem when input modification is allowed.