[Leetcode]数组+两个数组的交集 II

两个数组的交集 II

给定两个数组,编写一个函数来计算它们的交集。

示例 1:

输入: nums1 = [1,2,2,1], nums2 = [2,2]
输出: [2,2]

示例 2:

输入: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出: [4,9]

说明:

  • 输出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致。
  • 我们可以不考虑输出结果的顺序。

进阶:

  • 如果给定的数组已经排好序呢?你将如何优化你的算法?
  • 如果 nums1 的大小比 nums2 小很多,哪种方法更优?
  • 如果 nums2 的元素存储在磁盘上,磁盘内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Arrays;

class Solution {
	/*简述
	方法一给数组做一个标志位数组,空间复杂度为O(nums2.length)
	创建一个数组记录所有交集的元素,空间复杂度为O(nums2.length)
	先遍历数组一,再遍历数组二,时间复杂度为O(nums1.length*nums2.length)
	执行用时:21 ms
	内存消耗 : 36.2 MB
	 */
    public static int[] intersect1(int[] nums1, int[] nums2) {
    	int len1=nums1.length;
    	int len2=nums2.length;
    	boolean[] benchmark=new boolean[len2];
    	ArrayList<Integer> intersection=new ArrayList<Integer>();
    	for(int i=0;i<len1;i++) {
    		for(int j=0;j<len2;j++) {
    			if(nums1[i]==nums2[j] && !benchmark[j]) {
    				intersection.add(nums2[j]);
    				benchmark[j]=true;
    				break;
    			}
    		}
    	}
    	int[] d=new int[intersection.size()];
    	int index=0;
    	for(int key:intersection) {
    		d[index++]=key;
    	}
    	return d;
    	
    }
    
    /*简述
       方法二使用Map,数组作为键值key,计数器作为value
	先遍历数组1,给数组1做一个HashMap,空间复杂度为O(2nums1.length),时间复杂度为O(nums1.length)
	再遍历数组2,创建一个数组记录所有交集的元素,空间复杂度为O(nums2.length),时间复杂度为O(nums2.length)
	执行用时:10 ms
	内存消耗 : 36.1 MB
      */
     
    public static int[] intersect2(int[] nums1,int[] nums2) {
    	Map<Integer,Integer>map=new HashMap<Integer,Integer>();
    	for(int i=0;i<nums1.length;i++) {
    		Integer val=map.get(nums1[i]);
    		map.put(nums1[i],(val==null)?1:++val);
    	}
    	ArrayList<Integer> intersection=new ArrayList<Integer>();
    	for(int j=0,val;j<nums2.length;j++) {

    		if (map.containsKey(nums2[j]) && (val=map.get(nums2[j]))>0) {
    			intersection.add(nums2[j]);
    			map.put(nums2[j],--val);
    		}
    	}
    	int[] result=new int[intersection.size()];
    	int index=0;
    	for(int value:intersection) {
    		result[index++]=value;
    	}
    	
    	return result;
    }
    
    /*
       方法三 排好序后比较移动指针
       较好的情况,循环次数为O[2min(nums1.length+nums2.length)]
       最差的情况下,循环次数最多为O(nums1.length+nums2.length)
       创建一个数组记录所有交集的元素,空间复杂度为O(nums2.length)
       执行用时 : 7 ms, 
	内存消耗 : 36.1 MB*/
    public static int[] intersect3(int[] nums1,int[] nums2) {
    	Arrays.sort(nums1);
    	Arrays.parallelSort(nums2);
    	int len1=nums1.length;
    	int len2=nums2.length;
    	ArrayList<Integer> intersection=new ArrayList<Integer>();
    	for(int i=0,j=0;i<len1 && j<len2;) {
    		if(nums1[i]==nums2[j]) {
    			intersection.add(nums1[i]);
    			i++;
    			j++;
    		}
    		else if(nums1[i]>nums2[j]) 
    			j++;
    		
    		else
    			i++;
    	}
    	int index=0;
    	int[] result=new int[intersection.size()];
    	for(int value:intersection)
    		result[index++]=value;
    	return result;
    }
    
    public static void main(String[] args) {
    	int nums1[]= {9,4,9,8,4};
    	int nums2[]={4,9,4,5};
    	int result[]=intersect3(nums1, nums2);
    	for(int i=0;i<result.length;i++)
    		System.out.println(result[i]);  

    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值