-1

Suppose i have an array like

int array[] = {1,1,1,4,5,7,7,9,11};

I should be able to remove all the duplicates and hence my output should be {1,4,5,7,9,11}.

Constraints:

  • I am not allowed to use any kind of extra memory apart from variables
  • I should be able to resize the array
  • I am not allowed to use containers like Hashset or set etc:
  • Should be done in O(n) time
thkala
  • 84,049
  • 23
  • 157
  • 201
jerry
  • 274
  • 2
  • 19

3 Answers3

2

If the array is sorted, then this logic could be applied.

  1. Have two pointers(P1,P2) pointing to the beginning of the array.
  2. Increment pointer P2. Check if the value pointed by P2 and P1 are equal.
  3. If yes, increment further and reach to the point where P1 and P2 pointed values are not equal. Now go to step 5.
  4. If no, assign P1 to P2 and repeat from step 2.
  5. Now, remove the elements between P1 and P2. Assign P2 to P1.

Repeat the process until you reach the end point of the array.

Mahesh
  • 34,573
  • 20
  • 89
  • 115
  • how can you remove elements from an array like that ?? – jerry Oct 08 '11 at 04:02
  • Array **cannot** be resized. But in your question, you mentioned it is resizable. – Mahesh Oct 08 '11 at 04:03
  • Sorry i did not specify it clearly. By resizing i meant that we are supposed to put something like '\0' after rearranging the elements, and print the array until null is found – jerry Oct 08 '11 at 05:13
1

Traverse the array and compare each element with the previous element. If its the same, you know its a duplicate. Keep another pointer that copies each unique element within the array. Eg. 1,1,4,5,7,7,9,11

Keep two pointers i and j at starting of array i.e. 1.
Use i to traverse the array and j to keep track of the unique element. Initially, 1 is unique so copy a[i] to a[j] and increment both.
Next 1 is duplicate, so only increment j.
When 4 encountered, its unique, so copy a[i] to a[j] (j points to the second i.e. the duplicate 1) and increment both.
Do the same till i fully traverses the array.
a[0...j] gives all unique elements.

Complexity: O(n)

ggupta1612
  • 21
  • 2
0

If you know a maximum value (MAX_INT_VALUE) for the ints and aren't worried about memory constraints, this is a somewhat creative solution that got me through a job interview:

public int* removeDuplicates(int* array, int arraySize) {

    short indexMarkers [MAX_INT_VALUE];
    int i = 0;
    for (i=0; i<arraySize;i++) {
        indexMarkers[array[i]]++;
    }

    int cursor = 0;
    for(i=0; i<MAX_INT_VALUE;i++) {
        if (indexMarkers[i] > 0) {
            array[cursor] = i;
            cursor++;
        }
    }

    //resize array to be sizeof(int)*cursor

    return array;
}

The idea is to have the values of the items in the array be the indices of the indexMarkers array. Then you're just checking whether the value existed at all to output the new array. This would be at least O(2N) though.

John Leehey
  • 22,052
  • 8
  • 61
  • 88
  • Full points for creativity, but there are 2 problems with this: 1) One of the requirements was that you could not allocate extra memory. 2) This requires 2 passes over the array, while the trivial solution (assuming the array is sorted) requires only 1 pass over the array. – riwalk Oct 07 '11 at 23:08
  • Thanks steve. meh it was closed anyway. – John Leehey Oct 07 '11 at 23:09
  • 1
    @Stargazer712 I never said it was faster. But you're right I didn't heed the extra memory constraint. This way will work even if the array is not sorted as well. – John Leehey Oct 07 '11 at 23:11