ヒストグラム( として表されますMap<Integer,Integer>
)を作成し、次のことを行うことができます。
- list1 からヒストグラムにすべての要素 (およびその繰り返し数) を挿入します。
- 各要素 e に対して list2 を繰り返し
ます。
このソリューションは、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));
}
リストをソートし、リストごとに1つのポインターを使用して並列に反復することで、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 を増やす