对于给定的列表,请说[ "a", "a", "b", "c", "c" ]
我需要[ "b" ]
(仅非重复元素)作为输出。请注意,这与使用作业的Set
界面不同...
我在Java中编写了以下代码:
void unique(List<String> list) {
Collections.sort(list);
List<String> dup = new ArrayList<>();
int i = 0, j = 0;
for (String e : list) {
i = list.indexOf(e);
j = list.lastIndexOf(e);
if (i != j && !dup.contains(e)) {
dup.add(e);
}
}
list.removeAll(dup);
}
它有效...但是对于大小为85320的列表,几分钟后结束!
答案 0 :(得分:5)
你最好的表现是设置:
String[] xs = { "a", "a", "b", "c", "c" };
Set<String> singles = new TreeSet<>();
Set<String> multiples = new TreeSet<>();
for (String x : xs) {
if(!multiples.contains(x)){
if(singles.contains(x)){
singles.remove(x);
multiples.add(x);
}else{
singles.add(x);
}
}
}
这是一次传递,插入,删除和包含是log(n)。
答案 1 :(得分:5)
使用Java 8流:
{{1}}
答案 2 :(得分:0)
你可以使用地图。执行以下操作
$('#calendar').fullCalendar('removeEvents', calEvent._id);
答案 3 :(得分:0)
鉴于您可以对列表进行排序,关于最有效的方法是使用ListIterator
迭代相邻元素的运行:
List<String> dup = new ArrayList<>();
Collections.sort(list);
ListIterator<String> it = list.listIterator();
while (it.hasNext()) {
String first = it.next();
// Count the number of elements equal to first.
int cnt = 1;
while (it.hasNext()) {
String next = it.next();
if (!first.equals(next)) {
it.previous();
break;
}
++cnt;
}
// If there are more than 1 elements between i and start
// it's duplicated. Otherwise, it's a singleton, so add it
// to the output.
if (cnt == 1) {
dup.add(first);
}
}
return dup;
ListIterator
对于不支持随机访问的列表(如LinkedList
)比使用基于索引的访问更有效。
答案 4 :(得分:0)
您可以使用streams
以更简单的步骤实现此目的,如下所示,并带有内联注释:
//Find out unique elements first
List<String> unique = list.stream().distinct().collect(Collectors.toList());
//List to collect output list
List<String> output = new ArrayList<>();
//Iterate over each unique element
for(String element : unique) {
//if element found only ONCE add to output list
if(list.stream().filter(e -> e.equals(element)).count() == 1) {
output.add(element);
}
}