我看到很多主题相同的帖子(大多数是关于字符串的帖子),但是找不到我的问题的答案。如何从ArrayList中删除重复的整数?
import java.util.*;
public class ArrayList2 {
public static ArrayList<Integer> removeAllDuplicates(ArrayList<Integer> list) {
Collections.sort(list);
for (int i = 0; i < list.size(); i++) {
if (list.get(i) == list.get(i + 1)) {
list.remove(i);
}
}
return list;
}
}
这是我代码的开始,出现的唯一问题是,如果有3个具有相同值的整数,则只会删除其中一个。如果输入4,它将删除其中两个。 请不要哈希!
运行时的ArrayList和输出:
List: [-13, -13, -6, -3, 0, 1, 1, 1, 5, 7, 9]
Duplicates Removed: [-13, -6, -3, 0, 1, 1, 5, 7, 9]
这是我第一次使用此网站,所以请让我知道我在格式化方面是否做错了/是否已经回答了我遗漏的问题。
答案 0 :(得分:3)
removeAllDuplicates
函数不起作用的特定原因是,在成功比较之后您仍在迭代。如果仅在list.get(i) != list.get(i + 1)
时进行迭代,则将消除所有重复项。
public static ArrayList<Integer> removeAllDuplicates(ArrayList<Integer> list) {
Collections.sort(list);
int i = 0;
while(i < list.size() - 1) {
if (list.get(i) == list.get(i + 1)) {
list.remove(i);
} else {
i++;
}
}
return list;
}
值得注意的是,上面的功能并不尽如人意。尽管迭代运行得足够快,但最重要的一步将是排序操作(O(n log n))。
为避免这种额外的时间复杂性,请考虑使用HashSet而不是ArrayList(如果它仍然适合您的问题的限制)。
答案 1 :(得分:2)
其他人已经“回答”了if
语句跳过元素的基本问题,因为for-loop
正在增加索引位置,而数组的大小正在缩小。
这只是“另一个”可能的解决方案。就个人而言,我不喜欢在循环中更改List
,而是喜欢使用迭代器,例如...
Collections.sort(list);
Iterator<Integer> it = list.iterator();
Integer last = null;
while (it.hasNext()) {
Integer next = it.next();
if (next == last) {
it.remove();
}
last = next;
}
不过,我认为某种Set
将是一个更简单,更容易的解决方案(并且由于您不必对列表进行排序,因此效率更高;))
答案 2 :(得分:0)
这假设您由于诸如家庭作业之类的原因不能使用集合(“请不要散列!!!”)。
看看删除重复项会发生什么。假设您要删除的重复对象是3个连续相等数字中的第一个。
v
-13, -6, -3, 0, 1, 1, 1, 5, 7, 9
此处i
为4,表示3个1
值中的第一个。删除它后,所有后续元素都向下移动,因此第二个1
值现在取代了索引1
= 4处的第一个i
值。然后,当前迭代结束,另一个开始,i
现在是5。
v
-13, -6, -3, 0, 1, 1, 5, 7, 9
但是现在i
指的是剩下两个1
值中的第二个,并且下一个元素5
不相等,因此找不到重复项。
每次找到重复项时,都必须将i
减少1,以便可以停留在重复项的第一个元素上,以连续捕获3个或更多重复项。
v
-13, -6, -3, 0, 1, 1, 5, 7, 9
现在连续的元素仍然匹配,另一个1
值将被删除。
答案 3 :(得分:0)
您希望有一个double for循环,因为您不想只检查下一个索引,而是要检查所有索引。还要记住,当您删除一个值时,您想再次检查该删除的值,因为它可能会被另一个重复的值替换。