在O(n)时间内从C / C ++中删除数组中的重复项

时间:2011-10-07 22:41:45

标签: c

假设我有一个类似

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

我应该能够删除所有重复项,因此我的输出应该是{1,4,5,7,9,11}。

约束:

  • 除了变量
  • ,我不允许使用任何类型的额外内存
  • 我应该能够调整数组的大小
  • 我不允许使用像Hashset这样的容器或设置等:
  • 应该在O(n)时间内完成

3 个答案:

答案 0 :(得分:2)

如果数组已排序,则可以应用此逻辑。

  1. 有两个指针(P1,P2)指向数组的开头。
  2. 增加指针P2。检查P2和P1指向的值是否相等。
  3. 如果是,则进一步递增并到达P1和P2指向值不相等的点。现在转到第5步。
  4. 如果不是,请将P1指定给P2并从步骤2开始重复。
  5. 现在,删除P1和P2之间的元素。将P2分配给P1。
  6. 重复此过程,直到到达阵列的终点。

答案 1 :(得分:1)

遍历数组并将每个元素与前一个元素进行比较。如果它是相同的,你知道它是重复的。 保留另一个指针,复制数组中的每个唯一元素。 例如。 1,1,4,5,7,7,9,11

在数组的开始处保持两个指针i和j,即1.
使用i遍历数组和j以跟踪唯一元素。 原来, 1是唯一的,因此将[i]复制到[j]并增加两者 下一个1是重复的,所以只增加j。
当遇到4时,它是唯一的,所以将[i]复制到[j](j指向第二个,即副本1)并增加两者。
做同样的事情,直到我完全遍历阵列 a [0 ... j]给出所有独特元素。

复杂性:O(n)

答案 2 :(得分:0)

如果您知道整数的最大值(MAX_INT_VALUE)并且不担心内存限制,这是一个有点创造性的解决方案,让我通过面试:

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;
}

这个想法是让数组中的项的值是indexMarkers数组的索引。然后你只是检查是否存在该值以输出新数组。但这至少是O(2N)。