leetcode-350-两个数组的交集 II( Intersections of two arrays II)-java

题目及测试用例

package pid350;
/*两个数组的交集 II

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

例如:
给定 nums1 = [1, 2, 2, 1], nums2 = [2, 2], 返回 [2, 2].

注意:

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

跟进:

    如果给定的数组已经排好序呢?你将如何优化你的算法?
    如果 nums1 的大小比 nums2 小很多,哪种方法更优?
    如果nums2的元素存储在磁盘上,内存是有限的,你不能一次加载所有的元素到内存中,你该怎么办?
*/


public class main {
	
	public static void main(String[] args) {
		int[][] testTable = {{1,1,2},{1,1,2,2,5,6,7,7},{1,2,3,5},{1,1,1,1}};
		
			test(testTable[0],testTable[1]);
			test(testTable[2],testTable[3]);
		
	}
		 
	private static void test(int[] ito1,int[] ito2) {
		Solution solution = new Solution();
		int[] rtn;
		long begin = System.currentTimeMillis();
		for (int i = 0; i < ito1.length; i++) {
		    System.out.print(ito1[i]+" ");
		}//开始时打印数组
		System.out.println();
		for (int i = 0; i < ito2.length; i++) {
		    System.out.print(ito2[i]+" ");
		}//开始时打印数组
		
		rtn = solution.intersect(ito1,ito2);//执行程序
		long end = System.currentTimeMillis();		
		System.out.println("rtn=" );
		for (int i = 0; i < rtn.length; i++) {
		    System.out.print(rtn[i]+" ");
		}//打印结果几数组
		System.out.println();
		System.out.println("耗时:" + (end - begin) + "ms");
		System.out.println("-------------------");
	}

}

解法1(成功,8ms,有点慢)
通过map数据结构解决问题
首先,将nums1 数组中的元素 转为map1 的元素 key为数组中的数,对应的value为数的个数
然后,将nums2 数组中的元素与map1的元素作对比
如果map1中有,则map1的value-1,对应的,map2的value+1
最后将map2塞入list,再转为数组

package pid350;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class Solution {
	 public int[] intersect(int[] nums1, int[] nums2) {
	     HashMap<Integer, Integer> map1=new HashMap<Integer, Integer>();
	     //map1是nums1所有的元素填进去的map
	     HashMap<Integer, Integer> map2=new HashMap<Integer, Integer>();
	     //map2是nums 1 2 重叠的map
	     for(int i=0;i<nums1.length;i++){
	    	 Integer now=(Integer)nums1[i];
	    	 if(map1.containsKey(now)){
	    		 map1.put(now, map1.get(now)+1);
	    	 }
	    	 else{
	    		 map1.put(now,1);
	    	 }	    	 
	     }
	     
	     for(int i=0;i<nums2.length;i++){
	    	 Integer now=(Integer)nums2[i];
	    	 if(map1.containsKey(now)){	
	    		 
	    		 map1.put(now, map1.get(now)-1);
	    		 if(map1.get(now)==0){
	    			 map1.remove(now);
	    		 }
	    		 
	    		 if(map2.containsKey(now)){
		    		 map2.put(now, map2.get(now)+1);
		    	 }
		    	 else{
		    		 map2.put(now,1);
		    	 }	
	    	 }	    	 
	     }
	     List<Integer> resultList=new ArrayList<Integer>();
	     for(Integer key:map2.keySet()){
	    	 for(int i=0;i<map2.get(key);i++){
	    		 resultList.add(key);
	    	 }
	     }
	     int[] result=new int[resultList.size()];
	     for (int i=0;i<result.length;i++){
	    	 result[i]=resultList.get(i);
	     }
	     
		 return result;
	    }

}

解法2(别人的,成功,5ms,比较快)
这个解法思路与上一个一样,不过做了优化
1判断map的key是否为空做的很好
2 最后直接把结果加入list而不是先加入map再加入list

public class Solution {
    public int[] intersect(int[] nums1, int[] nums2) {
        Map<Integer, Integer> map1 = new HashMap<>();
        for(int num: nums1) {
            Integer count = map1.get(num);
            if (count == null) count = 1; else count ++;
            map1.put(num, count);
        }
        List<Integer> list2 = new ArrayList<>();
        for(int num: nums2) {
            Integer count = map1.get(num);
            if (count == null) continue;
            list2.add(num);
            count --;
            if (count == 0) map1.remove(num); else map1.put(num, count);
        }
        int[] result = new int[list2.size()];
        for(int i=0; i<list2.size(); i++) result[i] = list2.get(i);
        return result;
    }
}

解法3(成功,4ms,很快)
采用排序的算法,先用array的方法排序,再使用双指针算法比较,
相等则加入list,两个指针各自向后移1位
哪个小,就小的对应指针向后移1位
速度比之前快,主要是如果一方的长度很小,有可能可以很快算完

	public int[] intersect(int[] nums1, int[] nums2) {
		//先对数组进行排序
		Arrays.sort(nums1);
		Arrays.sort(nums2);
		//双指针,i对应nums1,j对应nums2
		int i=0;
		int j=0;
		//结果list
		List<Integer> list=new ArrayList<>();
		while(i<nums1.length&&j<nums2.length){
			if(nums1[i]==nums2[j]){
				//相等则加入list,两个指针各自向后移1位
				list.add(nums1[i]);
				i++;
				j++;
				continue;
			}
			if(nums1[i]<nums2[j]){
				//哪个小,就小的对应指针向后移1位
				i++;
			}
			else{
				j++;
			}			
		}
		//将list变成数组
		int[] result=new int[list.size()];
		for(i=0;i<list.size();i++){
			result[i]=list.get(i);
		}
		return result;				
    }
	

解法4 计数排序
计数排序在面对重复的问题,可以一定程度上代替hashmap,但是计数排序的长度为max-min+1,如果max-min是int的max和min,得到的长度会超过int,成为负数,因为java中数组的长度最大是int的max,不能超过它

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值