最快的稳定重复删除算法

时间:2011-05-06 15:35:14

标签: algorithm language-agnostic duplicate-removal

我有一个数组,我需要摆脱它的数组,没有重复。我必须保留原始数组中具有最小顺序的那些唯一元素。这大致是我的意思

NoDuplicate(A, value)
  for int i = 0 to i < A.length
    if A[i] == value
      return true
    i++
  return false

StableRemoveAlgo(A)      
  for int i = 0 to i < A.length
    if NoDuplicate(result, A[i])
      result.append(A[i])
  return result

如果算法比这个简单算法快?

更新:我无法对数组进行排序。我需要一个“稳定”版本的重复删除算法。因此,如果A[i] == A[j] and i < j算法必须删除元素A[j]

4 个答案:

答案 0 :(得分:7)

当您遍历数组时,将您遇到的每个(唯一)元素放入哈希表或树中。这将使您能够在检查k - 元素时快速检查 - 您是否在之前的k-1元素中遇到了相同的数字。

树会给你整体O(n log(n))时间复杂度。具有良好散列函数的散列表会做得更好(可能O(n))。

答案 1 :(得分:2)

如果元素的域是有限的(并且不是太大),则可以进行二进制计数排序。那将是O(n)。

否则,您可以使用临时Hashtable在迭代数组时存储元素,并且仅当元素当前不存在于哈希表中时才将元素放在输出数组中。在典型情况下,这将是O(n)。

答案 2 :(得分:1)

如果您不需要O(1)空间,只需为原始数组的元素(最初为0,1,2,...,n-1)创建一个索引数组,并使用它们进行排序,用于解析元素之间比较的索引号,否则将比较相等。这是在不稳定排序之上构建稳定排序的标准方法。之后,您只需运行索引数组即可找到要从原始数组中删除的元素。

答案 3 :(得分:0)

你是否可以在现场做事并对阵列进行排序?如果你这样做很简单:

sort(array) // use a stable sorting algorithm of your choice.
i = 0 //how many unique elements we have already spotted
j = 0 //how many array elements we have checked

while(j < arr.length){
    //found a new value:
    array[i] = array[j];

    //find next value in array that is different
    while(j < arr.length && array[i] == array[j]){
        j++;
    }
}
arr.length = i;

如果您需要自己实现稳定的排序算法,最简单的可能是Mergesort。

在这种情况下,您可以直接调整合并例程以忽略类似的值(优先于之前的值),而不是返回所有值。