Java 如何修改我的方法来搜索并删除O(N)或O(N*logn)中的重复项?
我创建了一个方法来搜索重复项,然后将重复项索引存储到另一个数组中。然后我在我的大数组中运行,移动所有条目而不重复 现在,我的问题是,这使用了ON*N,并且由于我添加了额外的数组,所以我使用了额外的内存空间 这怎么可能呢?假设我需要了解如何在不使用其他库或哈希集的情况下实现这一点 任何提示,谢谢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;
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更糟糕。在确定的线性时间内不可能找到重复的,这就是我想强调的。