Java 如何修改我的方法来搜索并删除O(N)或O(N*logn)中的重复项?

Java 如何修改我的方法来搜索并删除O(N)或O(N*logn)中的重复项?,java,arrays,duplicates,time-complexity,Java,Arrays,Duplicates,Time Complexity,我创建了一个方法来搜索重复项,然后将重复项索引存储到另一个数组中。然后我在我的大数组中运行,移动所有条目而不重复 现在,我的问题是,这使用了ON*N,并且由于我添加了额外的数组,所以我使用了额外的内存空间 这怎么可能呢?假设我需要了解如何在不使用其他库或哈希集的情况下实现这一点 任何提示,谢谢 public void dups() { int[] index = new int[100]; int k = 0; int n = 0;

我创建了一个方法来搜索重复项,然后将重复项索引存储到另一个数组中。然后我在我的大数组中运行,移动所有条目而不重复

现在,我的问题是,这使用了ON*N,并且由于我添加了额外的数组,所以我使用了额外的内存空间

这怎么可能呢?假设我需要了解如何在不使用其他库或哈希集的情况下实现这一点

任何提示,谢谢

   public void dups()
   {
       int[] index = new int[100];

       int k = 0;
       int n = 0;
       int p = 0;

       for (int i = 0; i < elements; i++)
           for (int j = i + 1; j < elements; j++)
               if(a[j].equals(a[i]))
                   index[k++] = i;

       for (int m = 0; m < elements; m++)
           if (m != index[p])
               a[n++] = (T) a[m];
           else
               p++;

       elements -= k;
   }
一般来说,在上找不到重复项

但是,在*日志n中也可以。只需在*log n上对数组进行排序,然后就可以在中完成重复项的扫描

另一方面,如果可以使用可能不想使用的哈希表,如果不想使用任何其他库,则可以扫描数组并计算每个元素在数组中出现的频率。之后,您可以遍历哈希表中的每个元素,并找到那些多次出现的元素。这将需要一个On的预期运行时,但不是确定性On

最后,为什么我写下你一般找不到重复的? 人们可以想象在一些特殊情况下,在这种情况下,在计算机上可以找到重复项。 例如,数组只能包含0到99之间的数字。 在这种情况下,可以使用另一个大小为100的数组来计算每个元素在数组中出现的频率。这与哈希表的工作方式相同,但它的运行时将是确定的

另一个可以在On中查找重复项的示例当然是,如果数组已经排序

一般情况下,在上找不到重复项

但是,在*日志n中也可以。只需在*log n上对数组进行排序,然后就可以在中完成重复项的扫描

另一方面,如果可以使用可能不想使用的哈希表,如果不想使用任何其他库,则可以扫描数组并计算每个元素在数组中出现的频率。之后,您可以遍历哈希表中的每个元素,并找到那些多次出现的元素。这将需要一个On的预期运行时,但不是确定性On

最后,为什么我写下你一般找不到重复的? 人们可以想象在一些特殊情况下,在这种情况下,在计算机上可以找到重复项。 例如,数组只能包含0到99之间的数字。 在这种情况下,可以使用另一个大小为100的数组来计算每个元素在数组中出现的频率。这与哈希表的工作方式相同,但它的运行时将是确定的


另一个可以在On中查找重复项的示例当然是,如果数组已经排序

由于哈希和等于比较,此选项未启用,并使用LinkedHashSet,它是Java标准库的一部分,但可能足够接近:

public void dups() {
    Set<Integer> uniques = new LinkedHashSet<>();
    for (int i = 0; i < elements.length; i++) {
        uniques.add(elements[i]);
    }
    // todo: copy the set into a list, then call toArray() to get an array.
}

由于哈希和等于比较,此选项未启用,并使用LinkedHashSet,它是Java标准库的一部分,但可能足够接近:

public void dups() {
    Set<Integer> uniques = new LinkedHashSet<>();
    for (int i = 0; i < elements.length; i++) {
        uniques.add(elements[i]);
    }
    // todo: copy the set into a list, then call toArray() to get an array.
}
使用哈希集按时执行此操作:

public <T> int removeDups(T[] original) {
    HashSet<T> unique = new HashSet<T>();
    for (T item: original) {
        unique.add(item);
    }

    int size = unique.size();
    int curr = 0;
    for (int i = 0; i < original.length; i += 1) {
        if (unique.remove(original[i])) {
            original[curr] = original[i];
            curr++;
        }
    }

    return size;
}
请注意,这取决于列表元素的hashCode方法是否正确地将元素分布在HashSet中的bucket上,以实现。在最坏的情况下,这是在*m上,其中m是唯一元素的数量,因此您应该明确地测量它

此实现修改数组,并返回唯一元素的数量。尽管数组可能大于此值,但超过该点的元素应视为垃圾

它一次通过列表将项目添加到哈希集,一次通过添加项目是O1,另一次通过更新数组,因此它再次打开,假设哈希函数良好。

使用哈希集按时执行此操作:

public <T> int removeDups(T[] original) {
    HashSet<T> unique = new HashSet<T>();
    for (T item: original) {
        unique.add(item);
    }

    int size = unique.size();
    int curr = 0;
    for (int i = 0; i < original.length; i += 1) {
        if (unique.remove(original[i])) {
            original[curr] = original[i];
            curr++;
        }
    }

    return size;
}
请注意,这取决于列表元素的hashCode方法是否正确地将元素分布在HashSet中的bucket上,以实现。在最坏的情况下,这是在*m上,其中m是唯一元素的数量,因此您应该明确地测量它

此实现修改数组,并返回唯一元素的数量。尽管数组可能大于此值,但超过该点的元素应视为垃圾


它一次通过列表将项目添加到哈希集中添加一个项目是O1,另一次通过更新数组,因此它再次打开,假设一个好的哈希函数。

哈希映射的默认实现是基于数组的,并且是打开的。因此,如果您想要一个有趣的练习,您可以筛选HashMap的实现,以准确了解它是如何散列其键的。基本上,它使用键的hashCode并使用它在预定位置hashCode&arraylelength-1中索引数组,并将值存储在该索引处。如果您重复这个概念,使用值作为键和值,那么您将只有uniq 您的数组中的ue项

但是,如果有大量重复项,但只有唯一的值,则最终将得到一个包含大量空插槽的数组。填充阵列后,只需在阵列中循环一次即可移除所有空插槽。例如:将所有非空条目复制到列表中


它将打开,但需要2次传递-一次填充阵列,一次移除空插槽。它还需要一个与现有数组长度相同的附加数组,以及一个较小的数组或列表以获得唯一值的最终列表。

HashMap的默认实现是基于数组的,并且是基于。因此,如果您想要一个有趣的练习,您可以筛选HashMap的实现,以准确了解它是如何散列其键的。基本上,它使用键的hashCode并使用它在预定位置hashCode&arraylelength-1中索引数组,并将值存储在该索引处。如果重复这个概念,使用值作为键和值,那么数组中只有唯一的条目

但是,如果有大量重复项,但只有唯一的值,则最终将得到一个包含大量空插槽的数组。填充阵列后,只需在阵列中循环一次即可移除所有空插槽。例如:将所有非空条目复制到列表中


它将打开,但需要2次传递-一次填充阵列,一次移除空插槽。它还需要一个与现有数组长度相同的额外数组,以及一个较小的数组或列表以获得唯一值的最终列表。

不可能删除ON中的重复项。他并没有说不使用哈希表。不需要拆分头发,但可以使用哈希映射来完成ON。但我不确定no HashSet要求是否包括HashMap。不可能删除ON中的重复项。他没有说不使用哈希表。不分割头发,但ON可以使用HashMap完成。但我不确定no HashSet要求是否包括HashMap。这不是启用的,而是启用的,因为散列在恒定的预期时间内运行,而不是恒定的时间。我可能不应该通过创建另一个ArrayList来使用额外的内存。@HelpNeeder-这听起来像是一个错误。@Leems在这种情况下,On expected可能很好,并且很容易比On^2或On*log n有所改进。@Brigham哈希表的最坏情况比Onlog n更糟糕。我想强调的是,不可能在确定性线性时间内找到重复项。这不是启用,而是启用,因为哈希在恒定的预期时间内运行,不是固定时间。我可能不应该通过创建另一个ArrayList来让我的程序使用额外的内存。@HelpNeeder-我觉得这听起来像是一个错误。@在这种情况下,On expected可能非常好,并且很容易比^2或*log n有所改进。@Brigham哈希表的最坏情况比Onlog n更糟糕。在确定的线性时间内不可能找到重复的,这就是我想强调的。