使用谷歌收藏Multiset使这(代表明智)cakewalk(虽然我也喜欢Eyal's answer)。这可能不像其他人的时间/记忆方式那样有效,但是很清楚发生了什么。
假设列表包含本身内没有重复:
Multiset<Integer> counter = HashMultiset.create();
int totalLists = 0;
// for each of your ArrayLists
{
counter.addAll(list);
totalLists++;
}
List<Integer> inAll = Lists.newArrayList();
for (Integer candidate : counter.elementSet())
if (counter.count(candidate) == totalLists) inAll.add(candidate);`
如果名单可能包含重复的元素,它们可以通过一组第一传递:
counter.addAll(list) => counter.addAll(Sets.newHashSet(list))
最后,这也是理想如果你想以后可能需要一些额外的数据(比如,某些特定的价值是如何接近的)。
另一种方法略微修改的Eyal的(基本上折叠在一起通过一组过滤列表,然后保持所有重叠元素的动作),并且比以上更轻巧:
public List<Integer> intersection(Iterable<List<Integer>> lists) {
Iterator<List<Integer>> listsIter = lists.iterator();
if (!listsIter.hasNext()) return Collections.emptyList();
Set<Integer> bag = new HashSet<Integer>(listsIter.next());
while (listsIter.hasNext() && !bag.isEmpty()) {
Iterator<Integer> itemIter = listsIter.next().iterator();
Set<Integer> holder = new HashSet<Integer>(); //perhaps also pre-size it to the bag size
Integer held;
while (itemIter.hasNext() && !bag.isEmpty())
if (bag.remove(held = itemIter.next()))
holder.add(held);
bag = holder;
}
return new ArrayList<Integer>(bag);
}
你的第一解决方案将在O(n)时间做,没有额外的存储空间,我非常怀疑你可以打败它。 – Rubys 2010-05-04 13:10:06
感谢您为我的直觉添加一些严谨;) – Ankur 2010-05-04 13:22:29
如果您的两个列表是[1,1,2]和[1,1,3],您会期望输出是[1,1]还是简单地[1]?即,您是否希望保留重复的内容? – Adamski 2010-05-04 16:37:31