so i am trying to make this task : make a function that recieves an int array and size int n,the function checks for any duplicates and moves the duplicates to the end of the given array(numbers can be between -n to n),and return the number of unique elements. example:
Array before moving duplications: 7 1 3 7 1 6 5 Array after movingduplications: 7 1 3 6 5 7 1 The number of different elements in array: 5.
so i managed to make this in O(n):
int moveDuplicatesV1(int* arr, int n) {
int* aux = (int*)calloc((2 * n) + 1, sizeof(int));
assert(aux);
int uniq = 0;
int i;
int last = -1;
for (i = 0; i < n; i++) {
aux[arr[i] + n]++;
if (aux[arr[i] + n] == 1)
{
if (last != -1)
{
swap(arr + i, arr + last);
i = last;
}
last = i + 1;
}
else
uniq--;
if (aux[arr[i]] != 1)
uniq++;
}
return uniq;
}
and now i am trying to make this code in nlogn this is what i did so far:
int moveDuplicatesV2(int* arr, int n) {
int i = 0, j = 0, k = 0, uniq = 0, dubs = 0;;
int* temp = (int*)calloc(n,sizeof(int));
assert(temp);
for (j = 0; j < n; j++) {
temp[j]=arr[j];
}
merge_sort(temp, 0, n - 1);
for (i = 0; i < n; i++) {
int left = bin_search(temp[i], temp, n);
int right = bin_search_last(temp[i], temp, n);
if (left == -1 || right == -1) {
uniq++;
}
else {
dubs = bin_search_last(temp[i], arr, n);
swap(dubs, arr[n-1]);
uniq++;
}
}
return uniq;
}
but something wrong i dont get the output like its should be. if someone can explain and help it will be appreciated thanks.
here the functions that i used:
int bin_search(int key, int* a, int n)
{
int* low, * high, * mid;
low = a;
high = a + n - 1;
while (low <= high)
{
mid = low + (high - low) / 2;
if (key == *mid)
return 1;
else if (key < *mid)
high = mid - 1;
else
low = mid + 1;
}
return 0;
}
int bin_search_last(int key, int* a, int n)
{
int low, high, mid;
low = 0;
high = n - 1;
while (low <= high)
{
mid = (low + high) / 2;
if (key < a[mid])
high = mid - 1;
else
if (key > a[mid])
low = mid + 1;
else
if ((low == high) || (a[mid + 1] > key))
return mid;
else
low = mid + 1;
}
return -1;
}
void swap(int* v, int* u)
{
int temp;
temp = *v;
*v = *u;
*u = temp;
}
void merge(int* a, int p, int q, int r)
{
int i = p, j = q + 1, k = 0;
int* temp = (int*)malloc((r - p + 1) * sizeof(int));
assert(temp);
while ((i <= q) && (j <= r))
if (a[i] < a[j])
temp[k++] = a[i++];
else
temp[k++] = a[j++];
while (j <= r)
temp[k++] = a[j++];
while (i <= q)
temp[k++] = a[i++];
for (i = p, k = 0; i <= r; i++, k++)
a[i] = temp[k];
free(temp);
}
void merge_sort(int* a, int first, int last)
{
int middle;
if (first < last) {
middle = (first + last) / 2;
merge_sort(a, first, middle);
merge_sort(a, middle + 1, last);
merge(a, first, middle, last);
}
}