一个帖子http://www.iteye.com/topic/790362的一个题目。
有两个长度分别为m,n的非递减 整型数组,其中n>m*m, 求这两个数组的交集,要求复杂度尽可能低 。
如数组a:-1,4,5
数组b:-15,1,3,4,5,7,8,9,10,15
结果应该是:4,5
这道题要充分利用n > m * m的条件,而无论是归并的方式,还是hashset的方式复杂度都和两个数组的长度大小比例无关,复杂度都是n+m > m * m + m = m(m+1) = O(m^2)。
使用二分查找,从小的集合中的元素依次二分查找大集合,得到公共元素的复杂度为:
m * logn = m* log(m^2) = 2m * logm = O(m*logm),我感觉这也是题目的原意。
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class CommonElements {
public static Set<Integer> commonElements(int[] a,int[] b){
Set<Integer> commonElements = new HashSet<Integer>();//use set to avoid duplication
int[] temp;
if(a.length > b.length){//swap if a.length > b.length
temp = a;
a = b;
b = temp;
}
for(int e : a){//for each element in a binary search from b
int index,preIndex = 0;
index = Arrays.binarySearch(b,preIndex,b.length, e);
if(index >= 0){
preIndex = index;
commonElements.add(e);
}
}
return commonElements;
}
public static void main(String[] args) {
int[] a = {-1,4,5};
int[] b = {-15,1,3,4,5,7,8,9,10,15};
Set<Integer> commonElements = CommonElements.commonElements(a,b);
for (Integer element : commonElements) {
System.out.println(element);
}
}
}