使用谷歌收藏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