我想通过创建一个包含除重复项之外的所有元素的新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。这是正确的,那会是多长时间的复杂性?
答案 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)
答案 2 :(得分:0)
也许尝试更简单的事情:
Set<T> mySet = new HashSet<T>
mySet.addAll(myArray);
List<T> output = new ArrayList<T>(mySet);
这将花费O(n)时间复杂度,但会增加空间复杂性。