求两个数组的交集和并集

晚上闲来无事,想起前两天查资料时候,看到别人一篇博客标题关于数组的交集和并集,晚上也随便写写,权当督促自己坚持经常练习练习写写小Demo。如下,先来一段求有序数组的交集的代码,代码如下:

public static List<Integer> getIntersectionSorted(int[] a,int[] b){
		if(a == null || b == null)
			throw new NullPointerException("Array is Empty");
		List<Integer> mixList = new ArrayList<Integer>();
        int i = 0;
        int j = 0;
        while(i < a.length && j < b.length){
        	 if(a[i] == b[j]){
        		 mixList.add(a[i]);
        		 //当前结点值相同,所以下次判断结点,先往前移动一次再说
        		 do{   
        			 i++;
        		 }while(i < a.length -1 && a[i] == a[i+1]);//当前判断结点下一个结点值是否等于前一个,如果等于避免无谓的再一圈循环,直接移动到下一个结点
        		 
        		 do{
        			 j++;
        		 } while(j < b.length -1 && b[j] == b[j+1]);
        		 continue;
        	 }else if(a[i] > b[j]){
        		 j++;
        		 continue;
        	 }else if(a[i] < b[j]){
        		 i++;
        		 continue;
        	 }
        }
		return mixList;
	}
由以上代码我们知道上面的求法最差时间负责度为O(m+n)。如果我们的数组没有排序,以上的方式肯定行不通,下面贴出求两无序数组的并集的代码,代码如下:

 public static List<Integer> getIntersectionNotSortedUsingWhile(int[] a,int[] b){
		if(a == null || b == null)
			throw new NullPointerException("Array is Empty");
		List<Integer> mixList = new ArrayList<Integer>();
		int startIndex = 0;
		int i = 0;
		while(i<b.length){
			int temp = b[i];
			int j = startIndex;
			while(j <a.length){
				while(j < a.length -1 && a[j] == a[j+1]){
					j++;
				}
				if(a[j] == temp){//当前判断结点下一个结点值是否等于前一个,如果等于避免无意义的移动
					mixList.add(temp);
					swap(a,startIndex,j); //此处操作:将数组元素分成两部分,一部分已经判断过的元素,每次元素判断过后,将该元素移动到判断过的部分,下次判断从未判断部分开始继续判断
										  //因为已经添加到mixList的元素没有必要再下一次循环去判断的必要了。(类似插入排序的意思)
					startIndex++;
					break;
				}
				j++;
			}
			i++;
		}
		return mixList;
	} 	
   
	public static List<Integer> getIntersectionNotSortedUsingFor(int[] a,int[] b){
		if(a == null || b == null)
			throw new NullPointerException("Array is Empty");
		List<Integer> mixList = new ArrayList<Integer>();
		int startIndex = 0;
		for(int i = 0;i<b.length;i++){
			int temp = b[i];
			for(int j = startIndex;j<a.length;j++){
				while(j < a.length -1 && a[j] == a[j+1]){//当前判断结点下一个结点值是否等于前一个,如果等于避免无意义的移动
					j++;
				}
				if(a[j] == temp){
					mixList.add(temp);
					swap(a,startIndex,j);//同上
					startIndex++;
					break;
				}
			}
		}
		return mixList;
	} 
	
	public static void swap(int[] a,int m,int n){
		int temp = a[m];
		a[m] = a[n];
		a[n] = temp;
	}

以上代码可知,以上算法的效率可能没有达到最优,自己感觉效率还没有那么差吧,稍微借鉴了下插入排序做了小小的优化,时间复杂度也相对稳定。

下面把自己求两个数组的并集的练习也贴出来,有什么地方不对,还希望园友指出。先求有序两个数组的并集代码如下:

public static List<Integer> getUnionSetSorted(int[] a,int[] b){
		if(a == null || b == null)
			throw new NullPointerException("Array is Empty");
		List<Integer> mixList = new ArrayList<Integer>();
		int i = 0,j = 0;
		while(i < a.length && j < b.length){
			 if(a[i] == b[j]){
				 mixList.add(a[i]);
				 i++;
				 while(i< a.length -1 && a[i] == a[i+1]){ //判断当前元素和下一个元素是否重复,重复元素直接前进一位
					 i++;
				 }
				 j++;
				 while(j< b.length -1 && b[j] == b[j+1]){
					 j++;
				 }

			 }else if(a[i] < b[j]){
				 mixList.add(a[i]);
				 i++;
				 while(i< a.length -1 && a[i] == a[i+1]){
					 i++;
				 }
			 }else if(a[i] > b[j]){
				 mixList.add(b[j]);
				 j++;
				 while(j< b.length -1 && b[j] == b[j+1]){
					 j++;
				 }
		
			 }
		}
		while(i <a.length){ //判断合并循环退出时,a数组还没有添加完
			mixList.add(a[i]);
			i++;
			 while(i< a.length -1 && a[i] == a[i+1]){
				 i++;
			 }
		}
		while(j < b.length){//同上
			mixList.add(b[j]);
			j++;
			while(i< a.length -1 && a[i] == a[i+1]){
				 i++;
			 }
		}
		return mixList;
	}
该代码的最差时间负责度也为O(M + N)。

下面我们求两个无序数组的并集的实现,代码如下:

public static List<Integer> getUnionSetNotSorted(int[] a,int[] b){
		if(a == null || b == null)
			throw new NullPointerException("Array is Empty");
		List<Integer> mixList = new ArrayList<Integer>();
		for(int i = 0;i<a.length;i++){
			 if(!mixList.contains(a[i])){
				 mixList.add(a[i]);
			 }
		}
		for(int i = 0;i<b.length;i++){
			if(!mixList.contains(b[i])){
				mixList.add(b[i]);
			}
		}
		return mixList;
	}
该代码的实现时间负责度为O(n2)。最后求两个无序的数组的并集代码的效率还有待提高,暂时没有想到效率更高的实现,路过的园友还望不吝指教。





在C语言中,要找到两个数组交集并集,首先需要对数组进行排序(如果未排序的话),然后遍历这两个数组,比较它们的元素,从而得到交集并集。以下是实现这一功能的基本步骤: 1. 排序:由于数组可能未排序,为了方便操作,我们通常需要先对两个数组进行排序。可以使用任何排序算法,比如快速排序、归并排序等。 2. 并集:创建一个数组用于存放并集的结果。遍历两个数组,如果发现相同的元素,则将其添加到并集数组中;如果元素不同,则将较小的元素添加到并集数组中,直到任一数组遍历完成。如果第一个数组遍历完了,将第二个数组剩下的元素添加到并集数组中;反之亦然。 3. 交集:同样地,创建一个数组用于存放交集的结果。遍历两个数组,如果发现相同的元素,则将其添加到交集数组中。注意,由于数组已经排序,一旦当前元素不相等,就可以停止当前数组的遍历。 示例代码如下(仅提供算法思路,未实现全部细节): ```c #include <stdio.h> #include <stdlib.h> // 假设这里有一个用于排序的函数 sortArray() // void sortArray(int *arr, int size); // 假设这里有一个用于比较两个数组中是否存在某个元素的函数 findInArray() // int findInArray(int *arr, int size, int value); void printArray(int *arr, int size) { for(int i = 0; i < size; ++i) printf("%d ", arr[i]); printf("\n"); } int main() { int arr1[] = {1, 3, 4, 5, 7}; int arr2[] = {2, 3, 5, 6}; int size1 = sizeof(arr1) / sizeof(arr1[0]); int size2 = sizeof(arr2) / sizeof(arr2[0]); // 排序数组(此处省略排序代码) // sortArray(arr1, size1); // sortArray(arr2, size2); int *unionArray = (int *)malloc((size1 + size2) * sizeof(int)); int *intersectionArray = (int *)malloc((size1 < size2 ? size1 : size2) * sizeof(int)); // 并集处理(此处省略具体实现代码) // printArray(unionArray, ...); // 打印并集结果 // 交集处理(此处省略具体实现代码) // printArray(intersectionArray, ...); // 打印交集结果 // 清理内存 free(unionArray); free(intersectionArray); return 0; } ``` 在上面的代码中,省略了排序和查找的具体实现,以及并集交集的生成逻辑,因为这些部分是根据具体需来定制的。实际编码时,需要实现上述提到的排序函数和查找函数,并完成并集交集的处理代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值