Answer:
/**
* An array in which all elements except one are duplicate.,
* find that element
* */
#include "vector"
#include "algorithm"
#include "stdio.h"
using namespace std;
/** SOLUTION I
* Sort the array - O(n log(n))
* Find the duplicate - O(n) (single pass)
* */
void SortAndFind(vector&vec)
{
// O(n log(n))
sort(vec.begin(), vec.end() );
int i = 0;
int j = i + 1;
int n = vec.size();
// O(n)
for ( i = 0, j = i+1; j < n ; ++j)
{
if ( vec[j] != vec[i] )
{
if ( (j-i) == 1 )
{
/* non duplicate found at j */
printf("\n Non Duplicate (%s) %d \n", __func__, vec[i]);
return;
}
else
{
i=j;
}
}
}
// the last element is the duplicate
printf("\n Non Duplicate (%s) %d \n", __func__, vec[n-1]);
}
/** SOLUTION II , better than first solution.
* Heapify the array - O(n)
* Remove one element at a time and find the duplicate - O(log(n))
* This approach is better because there is no need to sort the entire array
* */
void HeapifyAndFind(vector&vec)
{
// Create the heap O(n)
make_heap(vec.begin(), vec.end() );
// Find the duplicate, by removing one element at a
// time.
//
int i = 0;
int n = vec.size();
for ( int j = i+1; j < n; ++j)
{
// vec[j-1] is the min element
make_heap( vec.begin() + i , vec.end() );
if ( vec[i] != vec[j] )
{
if ( (j-i) == 1 )
{
/* non duplicate found at j */
printf("\n Non Duplicate (%s) %d \n", __func__, vec[i]);
return;
}
else
{
i=j;
}
}
}
// the last element is the duplicate
printf("\n Non Duplicate (%s) %d \n", __func__, vec[n-1]);
}
int main(int argc, char *argv[])
{
if ( argc > 1 )
{
vectorvec1(argc-1);
vectorvec2(argc-1);
for (int i = 1; i <= argc-1; ++i)
{
vec1[i-1] = atoi(argv[i]);
vec2[i-1] = atoi(argv[i]);
}
SortAndFind( vec1 );
HeapifyAndFind( vec2 );
}
return 0;
}
1 comment:
SOLUTION III:
1. XOR all the integers.
2. duplicate will cancel each other
3. non-duplicate remains
Time: O(n)
Space: O(1)
Assumption: Duplicity is 2, i.e., each duplicated element appears twice only.
Post a Comment