给定无序的整数流保持排序但删除在数组中恰好出现一次的元素

时间:2016-01-16 00:25:07

标签: java arrays algorithm hashmap

我的解决方案:

public class removeUniqueElements {
    public static Integer[] removeUnique(int[] arr){
        Map<Integer,Integer> output = new HashMap<Integer,Integer>();
        List<Integer> result = new ArrayList<Integer>();
        for(int i=0;i<arr.length;i++){
            if(output.containsKey(arr[i])){
                int count = output.get(arr[i]);
                count = count+1;
                output.put(arr[i],count);
            }
            else
            {
                output.put(arr[i],1);
            }
        }
        for(int i=0;i<arr.length;i++){
            if(output.get(arr[i])!=1){
                result.add(arr[i]);
            }
        }
        return result.toArray(new Integer[result.size()]);
    }

    public static void main(String[] args){
        int[] array = {1,2,3,4,2,3,4};
        Integer[] result = removeUnique(array);
        System.out.println(Arrays.toString(result));
    }
}

时间复杂度:O(n) 空间复杂度:O(n)

还有其他方法可以降低空间复杂度吗?请帮忙。

2 个答案:

答案 0 :(得分:1)

为了获得更好的性能,请使用Map<Integer, AtomicInteger>,这样您就可以简单地更新映射计数器,而不是每次增加计数器时都装箱一个新值。这也将减少产生的垃圾量,这可以被认为是内存占用的减少,即使它在技术上不是。

为减少内存占用,请勿使用List<Integer>Integer[]。将所有值装入Integer是很多对象开销,首先创建一个列表,然后是最终数组,意味着消耗引用数量的2倍。

相反,一旦构建了地图,计算要删除的值的数量,然后直接创建结果数组并填充它。 List没有装箱,也没有浪费空间。

我会留给您调整代码以进行这些改进。

答案 1 :(得分:1)

您可以使用Java8:

Arrays.stream(arr).collect(Collectors.groupingBy(Function.identity()).
       entrySet().stream().filter(e -> e.getValue().size() != 1).
       map(e -> e.getValue()).toArray(int[]::new);