0

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);
    }
}
MadneSs
  • 11
  • 1
  • 5
  • Both the V1 and V2 functions leak the memory they allocate. That's bad. – Jonathan Leffler Jan 08 '23 at 16:52
  • 2
    This question is popular this week. Similar recent questions can be found [here](https://stackoverflow.com/q/74987456/2505965) and [here](https://stackoverflow.com/q/75036301/2505965) and [here](https://stackoverflow.com/q/75011060/2505965) and [here](https://stackoverflow.com/q/75044525/2505965). Might be time to form a study group for this class? – Oka Jan 08 '23 at 17:14
  • 1
    "i managed to make this in O(n)" and " now i am trying to make this code in nlogn" really? – Support Ukraine Jan 08 '23 at 17:22
  • You can use a modified version of the mergesort (i.e. `merge`) to _only_ store unique elements at the front of the output array. And, put the dup elements working backwards from the end of the array. I'm sure at least one of the examples Oka linked to recommends this. So, no need to sort the array and then binsearch as the sorted final result will already have the number of unique and duplicate elements. – Craig Estey Jan 08 '23 at 19:00

0 Answers0