Find missing elements from an Array with duplicates
Given an array arr[] of size N having integers in the range [1, N] with some of the elements missing. The task is to find the missing elements.
Note: There can be duplicates in the array.
Examples:
Input: arr[] = {1, 3, 3, 3, 5}, N = 5
Output: 2 4
Explanation: The numbers missing from the list are 2 and 4
All other elements in the range [1, 5] are present in the array.
Input: arr[] = {1, 2, 3, 4, 4, 7, 7}, N = 7
Output: 5 6
Approach 1(Negating visited elements): The idea to solve the problem is as follows
In the given range [1, N] there should be an element corresponding to each index. So mark the visited indices by multiplying that element with -1. If an element is missing then its index will have a positive element. Otherwise, it will have a negative element.
Follow the below illustration:
Illustration:
Consider arr[] = {1, 3, ,3, 3, 5}
Here for illustration, we will use 1 based indexing
For i = 1:
=> arr[i] = 1. So mark arr[1] visited.
=> arr[1] = -1*arr[1] = -1*1 = -1
=> arr[] = {-1, 3, 3, 3, 5}
For i = 2:
=> arr[i] = 3. So mark arr[3] visited.
=> arr[3] = -1*arr[3] = -1*3 = -3
=> arr[] = {-1, 3, -3, 3, 5}
For i = 3:
=> arr[i] = -3. So we should move to absolute value of -3 i.e. 3
=> arr[3] is already visited. Skip to next index
=> arr[] = {-1, 3, -3, 3, 5}
For i = 4:
=> arr[i] = 3. So mark arr[3] visited.
=> arr[3] is already visited. Skip to next index
=> arr[] = {-1, 3, -3, 3, 5}
For i = 5:
=> arr[i] = 5. So mark arr[5] visited.
=> arr[5] = -1*arr[5] = -1*5 = -5
=> arr[] = {-1, 3, -3, 3, -5}
Again traverse the array. See that arr[2] and arr[4] are not visited.
So the missing elements are {2, 4}.
Follow the below steps to implement the idea:
- Traverse the array from i = 0 to N-1:
- If the element is negative take the positive value (say x = abs(arr[i])).
- if the value at (x-1)th index is not visited i.e., it is still positive then multiply that element with -1.
- Traverse the array again from i = 0 to N-1:
- If the element is not visited, i.e., has a positive value, push (i+1) to the resultant array.
- Return the resultant array that contains the missing elements.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
vector< int > missing_elements(vector< int > vec)
{
vector< int > mis;
for ( int i = 0; i < vec.size(); i++) {
int temp = abs (vec[i]) - 1;
vec[temp] = vec[temp] > 0
? -vec[temp] : vec[temp];
}
for ( int i = 0; i < vec.size(); i++)
if (vec[i] > 0)
mis.push_back(i + 1);
return mis;
}
int main()
{
vector< int > vec = { 3, 3, 3, 5, 1 };
vector< int > miss_ele = missing_elements(vec);
for ( int i = 0; i < miss_ele.size(); i++)
cout << miss_ele[i] << " " ;
return 0;
}
|
C
#include <stdio.h>
#include <stdlib.h>
void missing_elements( int vec[], int n)
{
int mis[n];
for ( int i = 0; i < n; i++)
mis[i] = -1;
for ( int i = 0; i < n; i++) {
int temp = abs (vec[i]) - 1;
vec[temp] = vec[temp] > 0 ? -vec[temp] : vec[temp];
}
for ( int i = 0; i < n; i++)
if (vec[i] > 0)
mis[i] = (i + 1);
int miss_ele_size = sizeof (mis) / sizeof (mis[0]);
for ( int i = 0; i < miss_ele_size; i++) {
if (mis[i] != -1)
printf ( "%d " , mis[i]);
}
}
int main()
{
int vec[] = { 3, 3, 3, 5, 1 };
int vec_size = sizeof (vec) / sizeof (vec[0]);
missing_elements(vec, vec_size);
return 0;
}
|
Java
import java.util.*;
class GFG {
static List<Integer>
missing_elements(List<Integer> vec)
{
List<Integer> mis = new ArrayList<Integer>();
for ( int i = 0 ; i < vec.size(); i++) {
int temp = Math.abs(( int )vec.get(i)) - 1 ;
if (( int )vec.get(temp) > 0 )
vec.set(temp, -( int )vec.get(temp));
else
vec.set(temp, vec.get(temp));
}
for ( int i = 0 ; i < vec.size(); i++) {
if (( int )vec.get(i) > 0 )
mis.add(i + 1 );
}
return mis;
}
public static void main(String args[])
{
List<Integer> vec = new ArrayList<Integer>();
vec.add( 3 );
vec.add( 3 );
vec.add( 3 );
vec.add( 5 );
vec.add( 1 );
List<Integer> miss_ele = missing_elements(vec);
for ( int i = 0 ; i < miss_ele.size(); i++)
System.out.print(miss_ele.get(i) + " " );
}
}
|
Python3
def missing_elements(vec):
mis = []
for i in range ( len (vec)):
temp = abs (vec[i]) - 1
if vec[temp] > 0 :
vec[temp] = - vec[temp]
for i in range ( len (vec)):
if (vec[i] > 0 ):
mis.append(i + 1 )
return mis
if __name__ = = '__main__' :
vec = [ 3 , 3 , 3 , 5 , 1 ]
miss_ele = missing_elements(vec)
for i in range ( len (miss_ele)):
print (miss_ele[i], end = " " )
|
C#
using System;
using System.Collections.Generic;
class GFG {
static List< int > missing_elements(List< int > vec)
{
List< int > mis = new List< int >();
for ( int i = 0; i < vec.Count; i++) {
int temp = Math.Abs(( int )vec[i]) - 1;
if (( int )vec[temp] > 0)
vec[temp] = -( int )vec[temp];
else
vec[temp] = vec[temp];
}
for ( int i = 0; i < vec.Count; i++) {
if (( int )vec[i] > 0)
mis.Add(i + 1);
}
return mis;
}
public static void Main(String[] args)
{
List< int > vec = new List< int >();
vec.Add(3);
vec.Add(3);
vec.Add(3);
vec.Add(5);
vec.Add(1);
List< int > miss_ele = missing_elements(vec);
for ( int i = 0; i < miss_ele.Count; i++)
Console.Write(miss_ele[i] + " " );
}
}
|
Javascript
<script>
function missing_elements(vec)
{
let mis = [];
for (let i = 0; i < vec.length; i++) {
let temp = Math.abs(vec[i]) - 1;
vec[temp] = vec[temp] > 0 ? -vec[temp] : vec[temp];
}
for (let i = 0; i < vec.length; i++)
if (vec[i] > 0)
mis.push(i + 1);
return mis;
}
let vec = [ 3, 3, 3, 5, 1 ];
let miss_ele = missing_elements(vec);
for (let i = 0; i < miss_ele.length; i++)
document.write(miss_ele[i] + " " );
</script>
|
Time Complexity: O(N).
Auxiliary Space: O(N)
Approach 2 (Performing in-place sorting): The idea in this case, is to use in-place sorting.
In the given range [1, N] there should be an element corresponding to each index. So we can sort them and then if at any index the position and the element are not same, those elements are missing.
For sorting the elements in linear time see the below pseudo code:
Pseudo Code:
Algorithm:
Start
Set pointer i = 0
while i < N:
pos = arr[i] – 1
If arr[pos] = pos + 1: // the element is in the correct position
i++
Else: // swap it to correct position
swap(arr[pos], arr[i])
end if
end while
for i = 0 to N-1:
If Arr[i] = i+1:
continue
Else:
i+1 is missing.
end if
end for
End
Follow the illustration below for a better understanding:
Illustration:
Consider arr[] = {3, 3, 3, 5, 1}
Example on how to sort in linear sort
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
vector< int > FindMissing(vector< int > arr)
{
int i = 0;
int N = arr.size();
while (i < N) {
int correct = arr[i] - 1;
if (arr[i] != arr[correct]) {
swap(arr[i], arr[correct]);
}
else {
i++;
}
}
vector< int > ans;
for (i = 0; i < N; i++) {
if (arr[i] != i + 1) {
ans.push_back(i + 1);
}
}
return ans;
}
int main()
{
vector< int > arr = { 1, 3, 3, 3, 5 };
vector< int > res = FindMissing(arr);
for ( int x: res)
cout << x << " " ;
return 0;
}
|
Java
import java.io.*;
import java.util.ArrayList;
import java.util.List;
class GFG
{
public static void main(String[] args)
{
int [] arr = { 1 , 3 , 3 , 3 , 5 };
System.out.println(FindMissing(arr));
}
static public List<Integer>FindMissing( int [] arr)
{
int i = 0 ;
while (i < arr.length) {
int correct = arr[i] - 1 ;
if (arr[i] != arr[correct])
{
swap(arr, i, correct);
}
else {
i++;
}
}
List<Integer> ans = new ArrayList<>();
for ( int index = 0 ; index < arr.length; index++) {
if (arr[index] != index + 1 ) {
ans.add(index + 1 );
}
}
return ans;
}
static void swap( int [] arr, int first, int second)
{
int temp = arr[first];
arr[first] = arr[second];
arr[second] = temp;
}
}
|
Python3
def FindMissing(arr):
i = 0
N = len (arr)
while (i < N):
correct = arr[i] - 1
if (arr[i] ! = arr[correct]):
temp = arr[i]
arr[i] = arr[correct]
arr[correct] = temp
else :
i + = 1
ans = []
for i in range (N):
if (arr[i] ! = i + 1 ):
ans.append(i + 1 )
return ans
arr = [ 1 , 3 , 3 , 3 , 5 ]
res = FindMissing(arr)
for x in range ( len (res)):
print (res[x], end = " " )
|
C#
using System;
using System.Collections;
public class GFG {
static public ArrayList FindMissing( int [] arr)
{
int i = 0;
while (i < arr.Length) {
int correct = arr[i] - 1;
if (arr[i] != arr[correct]) {
swap(arr, i, correct);
}
else {
i++;
}
}
ArrayList ans = new ArrayList();
for ( int index = 0; index < arr.Length; index++) {
if (arr[index] != index + 1) {
ans.Add(index + 1);
}
}
return ans;
}
static void swap( int [] arr, int first, int second)
{
int temp = arr[first];
arr[first] = arr[second];
arr[second] = temp;
}
static public void Main()
{
int [] arr = { 1, 3, 3, 3, 5 };
ArrayList res = FindMissing(arr);
for ( int i = 0; i < res.Count; i++) {
Console.Write(res[i] + " " );
}
}
}
|
Javascript
function FindMissing(arr)
{
let i = 0;
let N = arr.length;
while (i < N) {
let correct = arr[i] - 1;
if (arr[i] != arr[correct]) {
let temp = arr[i];
arr[i] = arr[correct];
arr[correct = temp];
}
else {
i++;
}
}
let ans = []
for (i = 0; i < N; i++) {
if (arr[i] != i + 1) {
ans.push(i + 1);
}
}
return ans;
}
let arr = [ 1, 3, 3, 3, 5 ];
let res = FindMissing(arr);
console.log(res);
|
Time Complexity: O(N)
Even in the worst case, there will be N-1 Swaps + N-1 Comparisons done. So asymptotically it’s O(N).
Auxiliary Space: O(N)
Last Updated :
17 Jan, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...