您可以构建直方图(将表示为 a Map<Integer,Integer>
)并且:
- 将 list1 中的所有元素(及其重复次数)插入直方图
- 为每个元素 e 迭代 list2:
- 如果直方图包含元素 e(具有正值):打印(或附加到新列表)e,并减少直方图中 e 的值
请注意,此解决方案是O(n+m)
时间(平均情况)和O(min{n,m})
空间。
代码示例(使用List<T>
而不是数组 - 但当然可以轻松修改):
private static <T> Map<T,Integer> populateHistogram(List<T> list) {
Map<T,Integer> histogram = new HashMap<T, Integer>();
for (T e : list) {
Integer val = histogram.get(e);
histogram.put(e, val == null ? 1 : val+1);
}
return histogram;
}
public static <T> List<T> generateInterectionList(List<T> list,Map<T,Integer> histogram ) {
List<T> res = new ArrayList<T>();
for (T e : list) {
Integer val = histogram.get(e);
if (val != null && val > 0) {
res.add(e);
histogram.put(e,val - 1);
}
}
return res;
}
public static <T> List<T> getIntersection(List<T> list1, List<T> list2) {
Map<T,Integer> histogram = populateHistogram(list1.size() > list2.size() ? list2 : list1);
return generateInterectionList(list1.size() > list2.size() ? list2 : list1,histogram);
}
public static void main(String[]args){
List<Integer> list1 = Arrays.asList(new Integer[]{1,2,5,4,1,3});
List<Integer> list2 = Arrays.asList(new Integer[]{1,2,1});
System.out.println(getIntersection(list1, list2));
}
请注意,它也可以在O(nlogn)
时间和O(logn)
空间上完成(用于排序算法的堆栈跟踪),对列表进行排序,然后为每个列表使用一个指针并行迭代
伪代码:
在 i1 < list1.length 和 i2 < list2.length 时重复:
- if list1[i1] == list2[i2]:
- 打印 list1[i1]
- 增加 i1,i2
- else if list1[i1] > list2[i2]:
- 增加 i2
- 否则:
- 增加 i1