【发布时间】:2014-03-04 00:09:08
【问题描述】:
我正在研究这个著名的面试问题,即在不使用 auxillary storage 的情况下删除 array 中的重复元素并保留顺序;
我已经阅读了很多帖子; Algorithm: efficient way to remove duplicate integers from an array, Removing Duplicates from an Array using C.
它们要么在C 中实现(没有解释),要么在[1,1,1,3,3] 等连续重复时提供的Java Code 会失败。
我对使用C 不太自信,我的背景是Java。所以我自己实现了代码;
如下:
- 使用两个循环,外循环遍历数组,内循环检查重复项,如果存在则将其替换为 null。
- 然后我检查重复替换空数组并删除空元素并将其替换为下一个非空元素。
-
我现在看到的总运行时间是
O(n^2)+O(n) ~ O(n^2)。阅读以上帖子,我明白这是我们能做的最好的事情,如果不允许排序和辅助存储。 我的代码在这里:我正在寻找进一步优化的方法(如果有可能)或better/simplisitc logic;public class RemoveDup { public static void main (String[] args){ Integer[] arr2={3,45,1,2,3,3,3,3,2,1,45,2,10}; Integer[] res= removeDup(arr2); System.out.println(Arrays.toString(res)); } private static Integer[] removeDup(Integer[] data) { int size = data.length; int count = 1; for (int i = 0; i < size; i++) { Integer temp = data[i]; for (int j = i + 1; j < size && temp != null; j++) { if (data[j] == temp) { data[j] = null; } } } for (int i = 1; i < size; i++) { Integer current = data[i]; if (data[i] != null) { data[count++] = current; } } return Arrays.copyOf(data, count); }}
编辑 1;来自@keshlam 的重新格式化代码抛出 ArrayIndexOutofBound 异常:
private static int removeDupes(int[] array) {
System.out.println("method called");
if(array.length < 2)
return array.length;
int outsize=1; // first is always kept
for (int consider = 1; consider < array.length; ++consider) {
for(int compare=0;compare<outsize;++compare) {
if(array[consider]!=array[compare])
array[outsize++]=array[consider]; // already present; advance to next compare
else break;
// if we get here, we know it's new so append it to output
//array[outsize++]=array[consider]; // could test first, not worth it.
}
}
System.out.println(Arrays.toString(array));
// length is last written position plus 1
return outsize;
}
【问题讨论】:
-
你的问题是?
-
@keshlam:以上第 3 点
-
我认为,在这种限制下,你不能做得比 O(N^2) 更好。所以代码看起来没问题。
-
我不认为
Arrays.copyOf()正在做你想做的事。 -
有一个我更喜欢的解决方案,它只需要通过外循环一次,但我不确定它在 O() 规模上是否更好。
标签: java arrays algorithm duplicate-removal