我创建了一个搜索重复项的方法,然后将重复项索引存储到另一个数组中。然后我正在运行我的大数组并移动所有条目而没有重复。
现在,我的问题是它使用O(N * N)并且我正在使用额外的内存空间,因为我正在添加额外的数组。
怎么可以这样做? 假设我需要了解如何在不使用其他库或HashSet的情况下完成此操作。
任何提示赞赏。
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;
}
答案 0 :(得分:4)
您无法在O(n)
(一般情况下)中找到重复项。
然而,可以在 O(n*log n)
中使用。只需对数组进行排序(O(n*log n)
),然后可以在O(n)
中完成对重复项的扫描。
另一方面,如果您可以使用哈希表(您可能不想这样做,如果您不想使用任何其他库),则可以扫描数组并计算每个元素出现的频率在数组中。之后,您可以遍历哈希表中的每个元素,并找到出现多次的元素。这将是 O(n)
的预期运行时,但不是确定性O(n)
。
最后,为什么我写了一般在O(n)
找不到重复内容?
可以想象几个特殊情况,在O(n)
中可以找到重复的情况。
例如,您的数组只能包含0到99之间的数字。
在这种情况下,您可以使用另一个数组(大小为100)来计算每个元素在数组中出现的频率。这与哈希表的工作方式相同,但其运行时将是确定性的O(n)
。
在O(n)
中查找重复项的另一个例子当然是,如果数组已经排序。
答案 1 :(得分:1)
使用HashSet
在O(n)时间内执行此操作:
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
中的存储区上分配元素以实现O(n)。在最坏的情况下,这是O(n * m),其中m是唯一元素的数量,所以你一定要测量它。
此实现修改了数组,并返回唯一元素的数量。虽然数组可能比这大,但是经过这一点的元素应该被视为垃圾。
在列表上进行一次传递,将项目添加到HashSet
(添加项目为O(1)),另一次传递更新数组,所以它是O(n)(再次,假设一个良好的哈希函数)。
答案 2 :(得分:0)
由于hash和equals比较,这不是O(n),并且使用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.
}
答案 3 :(得分:0)
HashMap的默认实现是基于数组的,是O(n)。因此,如果您想要一个有趣的练习,您可以筛选HashMap的实现,以准确理解它如何散列其键。基本上,它使用密钥的hashCode并使用它在预定位置索引数组(hashCode&amp; arraylength - 1),并将值存储在该索引处。如果你要重复这个概念,使用值作为键和值,你的数组中只有唯一的条目。
但是,如果您有大量重复项,但是只有唯一值,那么您最终会得到一个包含大量空插槽的数组。填充数组后,只需循环一次即可删除任何空插槽。 (例如:将所有非空条目复制到列表中)
它将是O(n),但需要2次传递 - 一次填充数组,一次删除空插槽。它还需要一个与现有数组相同长度的附加数组,以及一个较小的数组(或列表),以获得唯一值的最终列表。