Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 是否在数组中找到一个非重复元素?_Arrays_Algorithm_Time Complexity - Fatal编程技术网

Arrays 是否在数组中找到一个非重复元素?

Arrays 是否在数组中找到一个非重复元素?,arrays,algorithm,time-complexity,Arrays,Algorithm,Time Complexity,我有一个n元素数组,其中只有一个元素不重复,否则所有其他数字重复>1次。数组中的数字范围没有限制 一些解决办法是: 使用散列,但这将导致线性时间复杂度,但空间复杂度非常低 使用MergeSortO(nlogn)对列表进行排序,然后查找不重复的元素 有更好的解决方案吗?一种通用方法是实现bucketing技术(散列就是其中的一种技术),使用元素的标识(比如索引)将元素分配到不同的“bucket”中,然后找到大小最小的bucket(在您的示例中为1)。我认为,这个问题也被称为少数民族问题。在你的

我有一个
n
元素数组,其中只有一个元素不重复,否则所有其他数字重复>1次。数组中的数字范围没有限制

一些解决办法是:

  • 使用散列,但这将导致线性时间复杂度,但空间复杂度非常低
  • 使用MergeSort
    O(nlogn)
    对列表进行排序,然后查找不重复的元素

有更好的解决方案吗?

一种通用方法是实现bucketing技术(散列就是其中的一种技术),使用元素的标识(比如索引)将元素分配到不同的“bucket”中,然后找到大小最小的bucket(在您的示例中为1)。我认为,这个问题也被称为少数民族问题。在你的集合中,有多少个桶就有多少个独特的元素

通过散列来实现这一点是有问题的,因为冲突以及您的算法可能如何处理冲突。某些关联数组方法,例如trytes和可扩展散列,似乎不适用,因为它们更适合字符串

上述的一个应用是应用于。集合将是存储桶,您需要为数组中的每个元素调用MakeSet()和Find(),每次调用的成本为$O(\alpha(n))$,其中$\alpha(n)$是增长极慢的反向Ackermann函数。你可以认为它实际上是一个常数

当一个元素已经存在时,您必须进行联合。通过一些更改以最小基数跟踪集合,此解决方案应该可以工作。此解决方案的时间复杂度为$O(n\alpha(n))$


您的问题似乎也与问题无关。

如果您有严格的空间限制,请尝试多次扫描

假设输入有n个元素,您的内存中只能保存m个元素。如果您使用哈希表方法,在最坏的情况下,您需要处理n/2个唯一数字,以便希望m>n/2。如果没有那么大的m,可以将n个元素划分为k=(max(input)-min(input))/(2m)组,然后继续扫描n个输入元素k次(在最坏的情况下):

第一次运行:您只对get/put/mark/which元素进行散列,其值 第二次运行:仅对值在范围内(最小值(输入)+m*2,最小值(输入)+m*4)和 诸如此类


通过这种方式,你将时间复杂度折衷为O(kn),但你得到了空间复杂度界O(m)

我想到了两个想法:

  • 考虑到内存使用率为O(1),A可能比引用的合并排序更好,最坏情况下为O(nlogn),但最好情况下为O(n)

  • 基于的(相反)想法,您可以制作一种 使用树叶后,将其推向底部(而不是像八字树那样向上)。这仍然会给你一个类似的O(nlogn)植入,但优点是找到唯一元素的O(1)步骤,它将是根。排序算法是O(nlogn)+O(n)的和,该算法将是O(nlogn)+O(1)


否则,如您所述,使用基于哈希的解决方案(如哈希实现集)将导致O(n)算法(O(n)插入并添加计数引用,O(n)遍历集合以查找唯一元素),但您似乎不喜欢内存使用,尽管我不知道为什么。内存很便宜,现在…

哈希表实际上并没有占用那么多空间:
O(n)
。如果数组太大,您必须就地执行,那么您可能需要使用外部排序。哈希的空间复杂度最多为
O(n)
(对于一些较小的
x
,可能会有
C>x
,但具体取决于实现)。我喜欢“排序优先”的方法。是的,但是合并排序(就地)的空间复杂度为零。@Thilo只是在反作用于“非常差的空间复杂度”;)@亲爱的,数字的范围是多少并不重要。好的散列算法不关心范围是多少,只关心唯一元素的数量。想想原始散列,按存储空间进行模运算。不管数字有多大,它都能放进你的桌子。它不会就位,因为它需要与
n
成比例的额外存储空间,但不会很大。