我有一个数组,我需要摆脱它的数组,没有重复。我必须保留原始数组中具有最小顺序的那些唯一元素。这大致是我的意思
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]
答案 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。
在这种情况下,您可以直接调整合并例程以忽略类似的值(优先于之前的值),而不是返回所有值。