一尘不染

数组删除重复的元素

algorithm

我有一个未排序的数组,删除存在元素的所有重复项的最佳方法是什么?

例如:

a[1,5,2,6,8,9,1,1,10,3,2,4,1,3,11,3]

因此,执行该操作后,数组应如下所示

 a[1,5,2,6,8,9,10,3,4,11]

阅读 197

收藏
2020-07-28

共1个答案

一尘不染

检查每个元素与其他元素

天真的解决方案是将每个元素与其他每个元素进行检查。即使您只是“前进”,这也是浪费,并且会产生O(n 2)解决方案。

排序然后删除重复项

更好的解决方案是对数组进行排序,然后将每个元素检查到旁边的元素以查找重复项。选择一个有效的排序,这是O(n log n)。

基于排序的解决方案的缺点是无法维持订单。但是,额外的步骤可以解决此问题。将所有条目(在唯一的排序数组中)放入具有O(1)访问权的哈希表。然后遍历原始数组。对于每个元素,检查它是否在哈希表中。如果是,则将其添加到结果中并将其从哈希表中删除。您将得到一个结果数组,该数组具有原始元素的顺序,并且每个元素的位置与第一次出现的位置相同。

线性整数

如果您要处理某个固定范围的整数,则可以使用基数排序甚至更好。例如,如果假设数字都在0到1,000,000的范围内,则可以分配大约1,000,001的位向量。对于原始数组中的每个元素,都根据其值设置相应的位(例如,值13会导致设置第14位)。然后遍历原始数组,检查它是否在位向量中。如果是,则将其添加到结果数组中,并从位向量中清除该位。这是O(n),并交换时间空间。

哈希表解决方案

这使我们找到了所有解决方案中最好的解决方案:尽管有用,但实际上它是一种干扰。创建具有O(1)访问权限的哈希表。遍历原始列表。如果它不在哈希表中,则将其添加到结果数组中,然后将其添加到哈希表中。如果它在哈希表中,请忽略它。

到目前为止,这是最好的解决方案。那为什么要休息呢?因为这样的问题是关于使您拥有(或应该拥有)知识适应问题并根据您做出的假设对问题进行完善。制定解决方案并理解其背后的思想比反驳解决方案有用得多。

此外,哈希表并非始终可用。使用嵌入式系统或空间非常有限的东西。您可以在少数几个操作码中实现快速排序,远远少于任何哈希表。

2020-07-28