删除ArrayList中重复项的时间复杂度

时间:2018-01-18 20:31:51

标签: java arraylist time-complexity

我想通过创建一个包含除重复项之外的所有元素的新ArrayList来'删除'ArrayList中的元素。比较器选择重复,并保持排序。该算法只是迭代ArrayList并添加新列表中尚未存在的每个元素。这项工作是在一个遍历整个ArrayList并检查相等性的方法中完成的。这是代码:

public static <T> ArrayList<T> noDups(Comparator<T> cmp, ArrayList<T> l) {

    ArrayList<T> noDups = new ArrayList<T>();
    for(T o : l) {
        if(!isIn(cmp, o, l)) 
            noDups.add(o);
    }
    return noDups;
}

public static <T> boolean isIn(Comparator<T> cmp, T o, ArrayList<T> l) {
    Iterator<T> i = l.iterator();
    if (o==null) {
        while (i.hasNext())
            if (i.next()==null)
                 return true;
    } else {
        while (!(i.hasNext()))
            if (o.equals(i.next()))
                return true;
    }
    return false;
}

我很好奇这个算法的时间复杂度。我的想法是:第一步没有工作,因为ArrayList noDups是空的。对于第二步,有一个检查,对于第三步3,依此类推到n-1。所以我们有1 + 2 + ... + n-1。这是正确的,那会是多长时间的复杂性?

3 个答案:

答案 0 :(得分:4)

算法的时间复杂度为O(n^2),因为数组中每个元素的 ,您必须将其与 之前添加的每个元素进行比较。您可以使用O(n*log(n))将其改进为 O(n) Set

您提到您关心订单,据您所知,HashSet并未对其进行维护。它是 true ,但有一种方法可以让它发挥作用。像这样使用LinkedHashSet

ArrayList<Integer> array = 
    new ArrayList<>(Arrays.asList(1, 5, 4, 2, 2, 0, 1, 4, 2));
LinkedHashSet<Integer> set = new LinkedHashSet<>(array);

这将构建LinkedHashSet,插入,删除和查找的时间复杂度为O(1)。重要的部分是此数据结构与典型HashSet之间的差异。 LinkedHashSet还会创建一个链接列表,指示元素在插入方面的顺序。

如果您使用此循环运行上述代码:

for(Integer i : set) {
    System.out.print(i + " ");
}

输出结果为:1 5 4 2 0 - 如您所愿。

答案 1 :(得分:0)

你是正确的,它的时间复杂度将是O(N ^ 2)。但是,&#34;没有重复的列表&#34;是set的定义。这个question包含有关实施和角落案例的一些细节,可能涵盖您感兴趣的内容。

答案 2 :(得分:0)

也许尝试更简单的事情:

Set<T> mySet = new HashSet<T>
mySet.addAll(myArray);
List<T> output = new ArrayList<T>(mySet);

这将花费O(n)时间复杂度,但会增加空间复杂性。