rt,这是一个经典问题。
参考1:http://www.sysexpand.com/?path=exercises/array-intersection
参考2:http://leetcode.com/2010/03/here-is-phone-screening-question-from.html
用数组来模拟(本质上说集合中是没有重复元素的,这里用数组来模拟可以用重复元素),A、B数组长度分别为m和n。总的来说,分为以下几种方案。
方案1:两重循环判断(复杂度 O(m*n))
暴力方法,并且不容易去除重复元素
方案2:Hash Table方法(复杂度 O(m+n))
将A写入Hash Table,让后B在Hash Tabe中写入过程中判断重复即可。如果没有重复元素,唯一缺点是内存占用量大,可以使用《编程珠玑》中的BitMap方法节省内存。另外Hash过程中可能会有比较多的冲突。
另外,本方法不具有普遍性。
方案3:排序后对A中每个元素在B中进行二分查找(复杂度 O(nlogn+mlogm))
这里m<=n。否则排序后对B中每个元素在A中进行二分查找(复杂度 O(n*lgm))
注意,排序的复杂度是O(nlogn+mlogm),查找的复杂度是O(n*lgm)。
方案4:排序后应用归并排序的思想进行判断(复杂度 O(nlogn+mlogm))
指针i和j分别指向A和B的开头,如果对应元素相等即为交集,否则谁小谁的指针加1往后移动。
注意,排序的复杂度是O(nlogn+mlogm),归并过程是O(m+n),比方案3更优。
下面是实现部分,并且去除了重复元素。
/** * 创建时间:2014年8月16日 上午11:46:12 * 项目名称:Test * @author Cao Yanfeng Peking University * @since JDK 1.6.0_21 * 类说明:测试两个数组的交集,交集中不包含重复数 */ public class Intersectionof2ArraysTest { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub int[] array1={4,6,2,4,3,5,1}; int[] array2={4,4,9,6,8,7,5,5,6,7}; LinkedList<Integer> linkedList=Intersectionof2Arrays(array1, array2); for (Integer integer : linkedList) { System.out.println(integer); } } public static LinkedList<Integer> Intersectionof2Arrays(int[] array1,int[] array2) { LinkedList<Integer> linkedList=new LinkedList<Integer>(); int m=array1.length; int n=array2.length; quicSort(array1, 0,m-1); quicSort(array2, 0,n-1); /*初步判断两种没有任何交集的情况*/ if (array1[0]>array2[n-1]|array1[m-1]<array2[0]) { return linkedList; } int same=array1[0]-1;//有可能溢出 int i=0; int j=0; while (i<m&&j<n) { if (array1[i]==array2[j]) { /*去除重复数*/ if (same!=array1[i]) { linkedList.add(array1[i]); same=array1[i]; } i++; j++; }else if (array1[i]<array2[j]){ i++; }else { j++; } } return linkedList; } public static void quicSort(int[] arr, int start, int end) { if (start < end) { int middle = getMiddle(arr, start, end); quicSort(arr, start, middle - 1); quicSort(arr, middle + 1, end); } } public static int getMiddle(int[] arr, int start, int end) { int temp = arr[start]; while (start < end) { while (start < end && arr[end] >= temp) { end--; } arr[start] = arr[end]; while (start < end && arr[start] <= temp) {// 括号中end--之后可能不满足条件 start++; } arr[end] = arr[start]; } arr[start] = temp; return start; } }
A、B两个整数集合的交集
时间: 2024-11-05 16:27:00