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

标签 java arraylist time-complexity

我想通过创建一个新的 ArrayList 来“删除”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。这是正确的吗?时间复杂度是多少?

最佳答案

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

您提到您关心顺序,据您所知,HashSet 并不维护它。这是正确,但有一种方法可以让它发挥作用。像这样使用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 - 如您所愿。

关于java - 删除 ArrayList 中重复项的时间复杂度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48329822/

相关文章:

java - 访问其子类中抽象类的字段/方法/构造函数

java - 错误将此数据转换为日期 ("HH:mm a")、("dd MM")和 ("yyyy")。如何将其划分为 :D 部分

java - 当泛型不是协变时,为什么可以显式转换泛型类型数组?

android - Kotlin arrayList - 无法重写列表

c - 以下代码的复杂度是多少?

c++ - 计算图中路径的递归函数的复杂性

java - 使用互相关的声音文件的时间延迟

java - 从列表中获取随机字符串

javascript - 如何将从 MySQL 检索到的数组列表值设置到 JavaScript 中的文本框中?

Java 数据结构引用