删除数组中的重复项,结尾处填充为零

时间:2018-07-27 03:50:45

标签: java arrays

我有一个任务,要删除数组中的重复项,“删除”意味着将元素向下移动1,并使最后一个元素等于0, 所以如果我有int[] array = {1, 1, 2, 2, 3, 2};的输出应该是这样的: 1, 2, 3, 0, 0, 0 我尝试了这种逻辑:

public class ArrayDuplicates {
        public static void main(String[] args) {
            int[] array = {1, 1, 2, 2, 3, 2};
            System.out.println(Arrays.toString(deleteArrayDuplicates(array)));
        }

        public static int[] deleteArrayDuplicates(int[] array) {
            for (int i = 0; i < array.length; i++) {
                for (int j = i + 1; j < array.length; j++) {
                    if (array[i] == array[j]) { //this is for comparing elements
                        for (; i > 0; i--) {
                            array[j + 1] = array[j]; //this is for shifting
                        }
                        array[array.length - 1] = 0; //making last element equal to "0"
                    }
                }
            }
            return array;
        }
    }

但是它不起作用。.是否有人熟悉正确的解决方案? 非常感谢您的协助和关注。

7 个答案:

答案 0 :(得分:3)

您的代码:

简而言之,您选择的方法需要第三个循环变量k来代表当前正向左移动1个位置的索引。

  • i-当前唯一商品的位置
  • j-当前位置正在测试是否具有i上唯一项的相等性
  • k-由于j处的擦除操作,当前位置向左移动

建议:

一种更有效的方法是消除每次发现重复项时发生的重复左移,而是根据找到的重复项的数量来跟踪偏移:

private static int[] deleteArrayDuplicates(int[] array) {
    int dupes = 0; // total duplicates
    // i - the current unique item's position
    for (int i = 0; i < array.length - 1 - dupes; i++) {
        int idupes = 0; // duplicates for current value of i
        // j - the current position being tested for equality with unique item at i
        for (int j = i + 1; j < array.length - dupes; j++) {
            if (array[i] == array[j]) {
                idupes++;
                dupes++;
            } else if(idupes > 0){
                array[j-idupes] = array[j];
            }
        }
    }
    if(dupes > 0) {
        Arrays.fill(array, array.length-dupes, array.length, 0);
    }
    return array;
}

这与answer发布的dbl具有相似的复杂性,尽管由于最后消除了一些额外的循环,所以它应该稍微快一些。另一个优点是,与该答案不同,该代码不依赖于任何假设,即输入不应该包含零。

答案 1 :(得分:2)

@artshakhov: 这是我的方法,与您所找到的方法非常接近,但是使用的操作更少了。

private static int[] deleteArrayDuplicates(int[] array) {
    for (int i = 0; i < array.length - 1; i++) {
        if (array[i] == NEUTRAL) continue; //if zero is a valid input value then don't waste time with it
        int idx = i + 1;  //no need for third cycle, just use memorization for current shifting index.
        for (int j = i + 1; j < array.length; j++) {
            if (array[i] == array[j]) {
                array[j] = NEUTRAL;
            } else {
                array[idx++] = array[j];
            }
        }
    }
    return array;
}

答案 2 :(得分:1)

我刚刚编写了以下代码来回答您的问题。我对其进行了测试,并获得了您期望的输出。如果有任何我可能错过的特殊情况,我深表歉意,但它似乎适用于包括您在内的各种意见。

其背后的想法是,当我们遍历数组时,我们将使用哈希映射来跟踪是否已经在数组中看到特定元素。如果地图已经包含该元素-意味着我们已经在数组中看到该元素-我们将继续循环。但是,如果这是我们第一次看到该元素,则将更新j指向i指向的索引处的元素,然后递增j。

因此,基本上,通过j指针,我们能够将所有不同的元素移至数组的前面,同时确保其顺序与输入数组中的顺序相同。

现在,在第一个循环之后,我们的j指针指向数组中的第一个重复元素。我们可以将i设置为j并遍历数组的其余部分,使它们为零。

此算法的时间复杂度为O(N)。由于哈希表的原因,空间复杂度为O(N)。可能有一种方法可以在O(N)时间,O(1)空间中做到这一点。

public static int[] deleteArrayDuplicates(int[] array) {
        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        int j = 0;
        for (int i = 0; i < array.length; i++) {
            if (map.containsKey(array[i])) {
                    continue;
            }
            else {
                map.put(array[i],1);
                array[j] = array[i];
                j++;
            }
        }

        for (int i = j; i < array.length; i++) {
            array[i] = 0;
        }
        return array;
    }

如果您还有其他问题,请告诉我。

答案 3 :(得分:1)

花了几个小时尝试为我自己的解决方案,并创建了这样的内容:

public static int[] deleteArrayDuplicates(int[] array) {
    for (int i = 0; i < array.length; i++) {
        for (int j = i + 1; j < array.length; j++) {
            if (array[j] == array[i]) { //this is for comparing elements
                int tempIndex = j;
                while (tempIndex + 1 < array.length) {
                    array[tempIndex] = array[tempIndex + 1]; //this is for shifting elements down/left by "1"
                    array[array.length - 1] = 0; //making last element equal to "0"
                    tempIndex++;
                }
            }
        }
    }
    return array;
}

代码没有任何API帮助器,但似乎现在正在工作。

答案 4 :(得分:0)

尝试一下:

public static void main(String[] args)
{

    int a[]={1,1,1,2,3,4,5};
    int b[]=new int[a.length];
    int top=0;
    for( int i : a )
    {
        int count=0;
        for(int j=0;j<top;j++)
        {
            if(i == b[j])
                count+=1;
        }
        if(count==0)
        {
            b[top]=i;
            top+=1;
        }
    }
    for(int i=0 ; i < b.length ; i++ )
        System.out.println( b[i] );
}

说明:

创建另一个与给定数组大小相同的数组(b)。现在只需在数组 b 中仅包含唯一元素。仅当 b 中不存在数组 a 的元素时,才将其添加到数组 b

答案 5 :(得分:0)

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public class StackOverFlow {
    public static void main(String[] args) {
       int[] array = {1, 1, 2, 2, 3, 2};
   Set<Integer> set=new HashSet<>();
        for (int anArray : array) {
            set.add(anArray);
        }
        int[] a=new int[array.length];
        int i=0;
        for (Integer s:set) {
            a[i]=s;
            i++;
        }
        System.out.println(Arrays.toString(a));
    }
}

希望这个简单的方法对您有所帮助。 利用不允许重复的Set。

答案 6 :(得分:0)

我们可以使用 ARRAYLIST Java-8流功能来获取输出。

public static int[] deleteArrayDuplicates(int[] array) {
        List<Integer> list = new ArrayList(Arrays.stream(array).boxed().distinct().collect(Collectors.toList()));
        for (int i = 0; i < array.length; i++) {
            if (i < list.size()) {
                array[i] = list.get(i);
            } else {
                array[i] = 0;
            }
        }

        return array;
    }

输出

[1、2、3、0、0、0]