Algorithm: efficient way to remove duplicate integers from an array

前端 未结 30 2092
离开以前
离开以前 2020-11-22 16:03

I got this problem from an interview with Microsoft.

Given an array of random integers, write an algorithm in C that removes duplicated numbers an

相关标签:
30条回答
  • 2020-11-22 16:35

    Insert all the elements in a binary tree the disregards duplicates - O(nlog(n)). Then extract all of them back in the array by doing a traversal - O(n). I am assuming that you don't need order preservation.

    0 讨论(0)
  • 2020-11-22 16:38

    This is the naive (N*(N-1)/2) solution. It uses constant additional space and maintains the original order. It is similar to the solution by @Byju, but uses no if(){} blocks. It also avoids copying an element onto itself.

    #include <stdio.h>
    #include <stdlib.h>
    
    int numbers[] = {4, 8, 4, 1, 1, 2, 9};
    #define COUNT (sizeof numbers / sizeof numbers[0])
    
    size_t undup_it(int array[], size_t len)
    {
    size_t src,dst;
    
      /* an array of size=1 cannot contain duplicate values */
    if (len <2) return len; 
      /* an array of size>1 will cannot at least one unique value */
    for (src=dst=1; src < len; src++) {
            size_t cur;
            for (cur=0; cur < dst; cur++ ) {
                    if (array[cur] == array[src]) break;
                    }
            if (cur != dst) continue; /* found a duplicate */
    
                    /* array[src] must be new: add it to the list of non-duplicates */
            if (dst < src) array[dst] = array[src]; /* avoid copy-to-self */
            dst++;
            }
    return dst; /* number of valid alements in new array */
    }
    
    void print_it(int array[], size_t len)
    {
    size_t idx;
    
    for (idx=0; idx < len; idx++)  {
            printf("%c %d", (idx) ? ',' :'{' , array[idx] );
            }
    printf("}\n" );
    }
    
    int main(void) {    
        size_t cnt = COUNT;
    
        printf("Before undup:" );    
        print_it(numbers, cnt);    
    
        cnt = undup_it(numbers,cnt);
    
        printf("After undup:" );    
        print_it(numbers, cnt);
    
        return 0;
    }
    
    0 讨论(0)
  • 2020-11-22 16:38

    First, you should create an array check[n] where n is the number of elements of the array you want to make duplicate-free and set the value of every element(of the check array) equal to 1. Using a for loop traverse the array with the duplicates, say its name is arr, and in the for-loop write this :

    {
        if (check[arr[i]] != 1) {
            arr[i] = 0;
        }
        else {
            check[arr[i]] = 0;
        }
    }
    

    With that, you set every duplicate equal to zero. So the only thing is left to do is to traverse the arr array and print everything it's not equal to zero. The order stays and it takes linear time (3*n).

    0 讨论(0)
  • 2020-11-22 16:39

    The return value of the function should be the number of unique elements and they are all stored at the front of the array. Without this additional information, you won't even know if there were any duplicates.

    Each iteration of the outer loop processes one element of the array. If it is unique, it stays in the front of the array and if it is a duplicate, it is overwritten by the last unprocessed element in the array. This solution runs in O(n^2) time.

    #include <stdio.h>
    #include <stdlib.h>
    
    size_t rmdup(int *arr, size_t len)
    {
      size_t prev = 0;
      size_t curr = 1;
      size_t last = len - 1;
      while (curr <= last) {
        for (prev = 0; prev < curr && arr[curr] != arr[prev]; ++prev);
        if (prev == curr) {
          ++curr;
        } else {
          arr[curr] = arr[last];
          --last;
        }
      }
      return curr;
    }
    
    void print_array(int *arr, size_t len)
    {
      printf("{");
      size_t curr = 0;
      for (curr = 0; curr < len; ++curr) {
        if (curr > 0) printf(", ");
        printf("%d", arr[curr]);
      }
      printf("}");
    }
    
    int main()
    {
      int arr[] = {4, 8, 4, 1, 1, 2, 9};
      printf("Before: ");
      size_t len = sizeof (arr) / sizeof (arr[0]);
      print_array(arr, len);
      len = rmdup(arr, len);
      printf("\nAfter: ");
      print_array(arr, len);
      printf("\n");
      return 0;
    }
    
    0 讨论(0)
  • 2020-11-22 16:39

    this is what i've got, though it misplaces the order we can sort in ascending or descending to fix it up.

    #include <stdio.h>
    int main(void){
    int x,n,myvar=0;
    printf("Enter a number: \t");
    scanf("%d",&n);
    int arr[n],changedarr[n];
    
    for(x=0;x<n;x++){
        printf("Enter a number for array[%d]: ",x);
        scanf("%d",&arr[x]);
    }
    printf("\nOriginal Number in an array\n");
    for(x=0;x<n;x++){
        printf("%d\t",arr[x]);
    }
    
    int i=0,j=0;
    // printf("i\tj\tarr\tchanged\n");
    
    for (int i = 0; i < n; i++)
    {
        // printf("%d\t%d\t%d\t%d\n",i,j,arr[i],changedarr[i] );
        for (int j = 0; j <n; j++)
        {   
            if (i==j)
            {
                continue;
    
            }
            else if(arr[i]==arr[j]){
                changedarr[j]=0;
    
            }
            else{
                changedarr[i]=arr[i];
    
            }
        // printf("%d\t%d\t%d\t%d\n",i,j,arr[i],changedarr[i] );
        }
        myvar+=1;
    }
    // printf("\n\nmyvar=%d\n",myvar);
    int count=0;
    printf("\nThe unique items:\n");
    for (int i = 0; i < myvar; i++)
    {
            if(changedarr[i]!=0){
                count+=1;
                printf("%d\t",changedarr[i]);   
            }
    }
        printf("\n");
    }
    
    0 讨论(0)
  • 2020-11-22 16:40

    How about:

    void rmdup(int *array, int length)
    {
        int *current , *end = array + length - 1;
    
        for ( current = array + 1; array < end; array++, current = array + 1 )
        {
            while ( current <= end )
            {
                if ( *current == *array )
                {
                    *current = *end--;
                }
                else
                {
                    current++;
                }
            }
        }
    }
    

    Should be O(n^2) or less.

    0 讨论(0)
提交回复
热议问题