Find duplicate in an array in O(n) and by using O(1) extra space
Given an array arr[] containing n + 1 integers where each integer is between 1 and n (inclusive). There is only one duplicate element, find the duplicate element in O(n) time complexity and O(1) space.
Examples :
Input : arr[] = {1, 4, 3, 4, 2}
Output : 4
Input : arr[] = {1, 3, 2, 1}
Output : 1
Approach: Firstly, the constraints of this problem imply that a cycle must exist. Because each number in an array arr[] is between 1 and n, it will necessarily point to an index that exists. Therefore, the list can be traversed infinitely, which implies that there is a cycle. Additionally, because 0 cannot appear as a value in an array arr[], arr[0] cannot be part of the cycle. Therefore, traversing the array in this manner from arr[0] is equivalent to traversing a cyclic linked list. The problem can be solved just like linked list cycle.
Below is the implementation of above approach:
C++
#include <iostream>
using namespace std;
int findDuplicate( int arr[])
{
int slow = arr[0];
int fast = arr[0];
do {
slow = arr[slow];
fast = arr[arr[fast]];
} while (slow != fast);
int ptr1 = arr[0];
int ptr2 = slow;
while (ptr1 != ptr2) {
ptr1 = arr[ptr1];
ptr2 = arr[ptr2];
}
return ptr1;
}
int main()
{
int arr[] = { 1, 3, 2, 1 };
cout << findDuplicate(arr) << endl;
return 0;
}
|
C
#include <stdio.h>
int findDuplicate( int arr[])
{
int slow = arr[0];
int fast = arr[0];
do {
slow = arr[slow];
fast = arr[arr[fast]];
} while (slow != fast);
int ptr1 = arr[0];
int ptr2 = slow;
while (ptr1 != ptr2) {
ptr1 = arr[ptr1];
ptr2 = arr[ptr2];
}
return ptr1;
}
int main()
{
int arr[] = { 1, 3, 2, 1 };
printf ( "%d" , findDuplicate(arr));
return 0;
}
|
Java
import java.util.*;
class GFG
{
public static int findDuplicate( int []arr)
{
int slow = arr[ 0 ];
int fast = arr[ 0 ];
do
{
slow = arr[slow];
fast = arr[arr[fast]];
} while (slow != fast);
int ptr1 = arr[ 0 ];
int ptr2 = slow;
while (ptr1 != ptr2)
{
ptr1 = arr[ptr1];
ptr2 = arr[ptr2];
}
return ptr1;
}
public static void main(String[] args)
{
int []arr = { 1 , 3 , 2 , 1 };
System.out.println( "" +
findDuplicate(arr));
System.exit( 0 );
}
}
|
Python3
def findDuplicate(arr):
slow = arr[ 0 ]
fast = arr[ 0 ]
while True :
slow = arr[slow]
fast = arr[arr[fast]]
if slow = = fast:
break
ptr1 = arr[ 0 ]
ptr2 = slow
while ptr1 ! = ptr2:
ptr1 = arr[ptr1]
ptr2 = arr[ptr2]
return ptr1
if __name__ = = '__main__' :
arr = [ 1 , 3 , 2 , 1 ]
print (findDuplicate(arr))
|
C#
using System;
class GFG
{
public static int findDuplicate( int []arr)
{
int slow = arr[0];
int fast = arr[0];
do
{
slow = arr[slow];
fast = arr[arr[fast]];
} while (slow != fast);
int ptr1 = arr[0];
int ptr2 = slow;
while (ptr1 != ptr2)
{
ptr1 = arr[ptr1];
ptr2 = arr[ptr2];
}
return ptr1;
}
public static void Main()
{
int [] arr = {1, 3, 2, 1};
Console.WriteLine( "" +
findDuplicate(arr));
}
}
|
Javascript
<script>
function findDuplicate(arr)
{
let slow = arr[0];
let fast = arr[0];
do
{
slow = arr[slow];
fast = arr[arr[fast]];
} while (slow != fast);
let ptr1 = arr[0];
let ptr2 = slow;
while (ptr1 != ptr2)
{
ptr1 = arr[ptr1];
ptr2 = arr[ptr2];
}
return ptr1;
}
let arr = [ 1, 3, 2, 1 ];
document.write(findDuplicate(arr) + "<br>" );
</script>
|
PHP
<?php
function findDuplicate(& $arr )
{
$slow = $arr [0];
$fast = $arr [0];
do
{
$slow = $arr [ $slow ];
$fast = $arr [ $arr [ $fast ]];
} while ( $slow != $fast );
$ptr1 = $arr [0];
$ptr2 = $slow ;
while ( $ptr1 != $ptr2 )
{
$ptr1 = $arr [ $ptr1 ];
$ptr2 = $arr [ $ptr2 ];
}
return $ptr1 ;
}
$arr = array (1, 3, 2, 1);
echo " " . findDuplicate( $arr );
?>
|
Complexity Analysis:
- Time Complexity: O(N)
- Auxiliary Space: O(1)
Another Approach: Using XOR Operator
In this approach we will be using XOR property that A ^ A = 0 to find the duplicate element. We will first XOR all the elements of the array with 0 and store the result in the variable “answer”. Then we will XOR all the elements from 1 to n with the value in “answer”, and returns the final value of “answer” which will be the duplicate element.
1) Initialize an answer variable with 0
2) Iterate and XOR all the elements of array and update in answer variable
3) XOR answer with numbers 1 to n
Below is the implementation of above approach:
C++
#include <iostream>
using namespace std;
int findDuplicate( int arr[] , int n)
{
int answer=0;
for ( int i=0; i<n; i++){
answer=answer^arr[i];
}
for ( int i=1; i<n; i++){
answer=answer^i;
}
return answer;
}
int main() {
int arr[] = { 1, 3, 2, 1 };
int n = sizeof (arr) / sizeof (arr[0]);
cout << findDuplicate(arr,n);
return 0;
}
|
Java
import java.io.*;
class GFG {
public static int findDuplicate( int [] arr) {
int answer = 0 ;
int n = arr.length;
for ( int i = 0 ; i < n; i++) {
answer = answer ^ arr[i];
}
for ( int i = 1 ; i < n; i++) {
answer = answer ^ i;
}
return answer;
}
public static void main (String[] args) {
int [] arr = { 1 , 3 , 2 , 1 };
System.out.println(findDuplicate(arr));
}
}
|
Python
def find_duplicate(arr):
answer = 0
n = len (arr)
for i in range (n):
answer = answer ^ arr[i]
for i in range ( 1 , n):
answer = answer ^ i
return answer
arr = [ 1 , 3 , 2 , 1 ]
print (find_duplicate(arr))
|
C#
using System;
class GFG {
public static int findDuplicate( int [] arr) {
int answer = 0;
int n = arr.Length;
for ( int i = 0; i < n; i++) {
answer = answer ^ arr[i];
}
for ( int i = 1; i < n; i++) {
answer = answer ^ i;
}
return answer;
}
static void Main( string [] args) {
int [] arr = {1, 3, 2, 1};
Console.WriteLine(findDuplicate(arr));
}
}
|
Javascript
function findDuplicate(arr) {
let answer = 0;
const n = arr.length;
for (let i = 0; i < n; i++) {
answer = answer ^ arr[i];
}
for (let i = 1; i < n; i++) {
answer = answer ^ i;
}
return answer;
}
const arr = [1, 3, 2, 1];
console.log(findDuplicate(arr));
|
Complexity Analysis:
- Time Complexity: O(N)
- Auxiliary Space: O(1)
Another Approach: Marking the visited elements
We are given positive integers from 1 to n where the size of array is n + 1, So we are going to traverse the array, based on the elements as indices and mark the visited elements as -ve. The moment we arrive at the visited element (-ve element) we are going to return the index of that element.
1. i = nums[i]
2. If its -ve then return the i-th index else
3. Mark the arr[i] as -ve. Repeat STEP 1
Below is the implementation of above approach:
C++
#include <iostream>
#include <cmath>
#include<vector>
using namespace std;
int findDuplicate(vector< int >& arr) {
int i = 0;
while ( true ) {
i = abs (arr[i]);
if (arr[i] < 0) {
return i;
}
arr[i] = -1 * arr[i];
}
}
int main() {
vector< int > arr = {1, 2, 3, 1};
cout << findDuplicate(arr) << endl;
return 0;
}
|
Java
import java.util.*;
public class Main {
public static int findDuplicate(List<Integer> arr) {
int i = 0 ;
while ( true ) {
i = Math.abs(arr.get(i));
if (arr.get(i) < 0 ) {
return i;
}
arr.set(i, - 1 * arr.get(i));
}
}
public static void main(String[] args) {
List<Integer> arr = Arrays.asList( 1 , 2 , 3 , 1 );
System.out.println(findDuplicate(arr));
}
}
|
Python
import math
def findDuplicate(arr):
i = 0
while True :
i = int (math.fabs(arr[i]))
if arr[i] < 0 :
return i
arr[i] = - 1 * arr[i]
arr = [ 1 , 2 , 3 , 1 ]
print (findDuplicate(arr))
|
C#
using System;
using System.Collections.Generic;
class Program
{
static int FindDuplicate(List< int > arr)
{
int i = 0;
while ( true )
{
i = Math.Abs(arr[i]);
if (arr[i] < 0)
{
return i;
}
arr[i] = -1 * arr[i];
}
}
static void Main()
{
List< int > arr = new List< int > { 1, 2, 3, 1 };
Console.WriteLine(FindDuplicate(arr));
}
}
|
Javascript
function findDuplicate(arr) {
let i = 0;
while ( true ) {
i = Math.abs(arr[i]);
if (arr[i] < 0) {
return i;
}
arr[i] = -1 * arr[i];
}
}
let arr = [1, 2, 3, 1];
console.log(findDuplicate(arr));
|
Output
1
Complexity Analysis:
- Time Complexity: O(N)
- Auxiliary Space: O(1)
Another Approach: Place Element in the correct position
Keep placing elements in their correct position(equals to value) unless and until you find the element already present in its correct position. Thats how you found the duplicate element
Below is the implementation of above approach:
C++
#include <iostream>
void swap( int nums[], int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
int findDuplicate( int nums[]) {
while ( true ) {
int i = nums[0];
if (nums[i] != i) {
swap(nums, 0, i);
} else {
return i;
}
}
}
int main() {
int nums[] = {1, 2, 3, 1};
std::cout << findDuplicate(nums) << std::endl;
return 0;
}
|
Java
import java.io.*;
class GFG {
public static int findDuplicate( int [] nums)
{
while ( true ) {
int i = nums[ 0 ];
if (nums[i] != i) {
swap(nums, 0 , i);
}
else {
return i;
}
}
}
private static void swap( int [] nums, int i, int j)
{
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
public static void main(String[] args)
{
int [] nums = { 1 , 2 , 3 , 1 };
System.out.println(findDuplicate(nums));
}
}
|
Python
def findDuplicate(nums):
while True :
i = nums[ 0 ]
if nums[i] ! = i:
nums[ 0 ], nums[i] = nums[i], nums[ 0 ]
else :
return i
nums = [ 1 , 3 , 4 , 2 , 2 ]
print (findDuplicate(nums))
|
C#
using System;
public class GFG {
static void Swap( int [] nums, int i, int j)
{
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
static int FindDuplicate( int [] nums)
{
while ( true ) {
int i = nums[0];
if (nums[i] != i) {
Swap(nums, 0, i);
}
else {
return i;
}
}
}
static void Main()
{
int [] nums = { 1, 2, 3, 1 };
Console.WriteLine(FindDuplicate(nums));
}
}
|
Javascript
function findDuplicate(nums) {
while ( true ) {
let i = nums[0];
if (nums[i] !== i) {
[nums[0], nums[i]] = [nums[i], nums[0]];
} else {
return i;
}
}
}
let nums = [1, 3, 4, 2, 2];
console.log(findDuplicate(nums));
|
Output
1
Complexity Analysis:
- Time Complexity: O(N)
- Auxiliary Space: O(1)
Last Updated :
17 Dec, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...