我需要一个java代码,可以在不改变元素顺序的情况下从数组中删除重复项,而无需使用Sets或排序技术。
例如: 如果输入数组是{23,1,5,4,2,23,6,2,4} 然后输出应为{23,1,5,4,2,6}
答案 0 :(得分:3)
您可以在O(n^2)
时间内使用 O(1)额外空格进行此操作。
public static int[] noSpaceElementDistinctness(int[] arr) {
int n = arr.length;
for (int i = 0; i < n;i++) {
boolean exists = false;
for (int j = 0; j < i; j++) {
if (arr[i] == arr[j]) {
exists = true;
break;
}
}
if (exists) {
for (int j = i+1; j<n; j++)
arr[j-1] = arr[j];
n--;
i--; //to iterate the next element, which is now at index i, not i+1.
}
}
for (int i = n; i < arr.length; i++) arr[i] = Integer.MIN_VALUE; //indicates no value
return arr;
}
作为旁注,元素清晰度问题并不像从第一眼看起来那样有效地解决,而且它是一个严格的下限,你可以采取哪些措施来有效地解决它。 This thread讨论了它。
答案 1 :(得分:1)
如果你使用Java 8,一个简单的方法是:
int[] array = {23, 1, 5, 4, 2, 23, 6, 2, 4};
int[] noDupes = IntStream.of(array).distinct().toArray();
System.out.println(Arrays.toString(noDupes)); // [23, 1, 5, 4, 2, 6]
答案 2 :(得分:0)
创建一个新的ArrayList()。循环遍历旧列表并将值复制到new,除非它已经在其中。
订单将被更改,因为您不会复制所有...
答案 3 :(得分:0)
有几个选项 - 一些比其他选项更有效:
/**
* Brute force approach - very inefficient.
*
* Finds each duplicate and removes it.
*/
private int[] removeDupesUsingNoExtraMemory(int[] a) {
int length = a.length;
for (int i = 0; i < length - 1; i++) {
for (int j = i + 1; j < length; j++) {
if (a[i] == a[j]) {
// No point copying if this is the last one.
if (j < length - 1) {
// Remove a[j].
System.arraycopy(a, j + 1, a, j, length - j - 1);
}
length -= 1;
}
}
}
// Actually it does use extra memory but only to trim the array because Java cannot slice arrays.
return Arrays.copyOf(a, length);
}
/**
* A bit more efficient.
*
* Copies only non-duplicate ones.
*/
private int[] removeDupesDifferently(int[] a) {
int length = a.length;
// Copying to the end backwards.
int to = length - 1;
// Copy backwards so we remove the second duplicate - not the first.
for (int i = length - 1; i >= 0; i--) {
boolean duplicate = false;
for (int j = 0; j < i && !duplicate; j++) {
duplicate |= a[i] == a[j];
}
if (!duplicate) {
a[to--] = a[i];
}
}
return Arrays.copyOfRange(a, to + 1, a.length);
}
/**
* Most efficient - but uses a `Set`.
*
* Builds a `Set` of `seen` values so we don't copy duplicates.
*/
private int[] removeDupesUsingASet(int[] a) {
int to = 0;
Set<Integer> seen = new HashSet<>();
for (int i = 0; i < a.length - 1; i++) {
// Seen it before?
if (!seen.contains(a[i])) {
a[to++] = a[i];
// Seen that one - don't want to see it again.
seen.add(a[i]);
}
}
return Arrays.copyOf(a, to);
}
public void test() {
System.out.println("removeDupesUsingNoExtraMemory = " + Arrays.toString(removeDupesUsingNoExtraMemory(new int[]{23, 1, 5, 4, 2, 23, 6, 2, 4})));
System.out.println("removeDupesDifferently = " + Arrays.toString(removeDupesDifferently(new int[]{23, 1, 5, 4, 2, 23, 6, 2, 4})));
System.out.println("removeDupesUsingASet = " + Arrays.toString(removeDupesUsingASet(new int[]{23, 1, 5, 4, 2, 23, 6, 2, 4})));
}
答案 4 :(得分:0)
int arr[] = {23,1,5,4,2,6} ;
List<Integer> list = new ArrayList<Integer>();
for(int i = 0; i<arr.length; i++) {
if (!list.contains(arr[i])) {
list.add(arr[i]);
}
}
Iterator it = list.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
答案 5 :(得分:0)
如果您只需要在不修改阵列的情况下打印唯一元素,则可以使用此替代解决方案。使用O(n log n)对数组进行排序(例如,合并排序)并运行数组O(n)以仅打印其相邻元素不同的元素,即:
if( arr[i] != arr[i + 1]) {
print(arr[i]);
}
干杯!