350. Intersection of Two Arrays II

来源:互联网 发布:mac导入图片到iphone 编辑:程序博客网 时间:2024/05/18 17:27

问题链接:https://leetcode.com/problems/intersection-of-two-arrays-ii/

Given two arrays, write a function to compute their intersection.

Example:
Given nums1 = [1, 2, 2, 1]nums2 = [2, 2], return [2, 2].

Note:

  • Each element in the result should appear as many times as it shows in both arrays.
  • The result can be in any order.

Follow up:

  • What if the given array is already sorted? How would you optimize your algorithm?
  • What if nums1's size is small compared to nums2's size? Which algorithm is better?
  • What if elements of nums2 are stored on disk, and the memory is limited such that you cannot load all elements into the memory at once?


public class Solution {    public int[] intersect(int[] nums1, int[] nums2) {        if(nums1==null || nums2==null || nums1.length==0 || nums2.length==0) {            return new int[]{};        }                Map<Integer,Integer> map = new HashMap<Integer,Integer>();        List<Integer> res = new LinkedList<Integer>();                for(int i=0;i<nums1.length;i++) {            if(map.containsKey(nums1[i])) {                map.put(nums1[i],map.get(nums1[i])+1);            } else {                map.put(nums1[i],1);            }        }                for(int i=0;i<nums2.length;i++) {            if(map.containsKey(nums2[i])) {                res.add(nums2[i]);                if(map.get(nums2[i]) > 1) {                    map.put(nums2[i],map.get(nums2[i])-1);                } else {                    map.remove(nums2[i]);                }            }        }                int[] result = new int[res.size()];        for(int i=0;i<res.size();i++) {            result[i] = (int)res.get(i);        }                return result;    }}

参考答案:https://leetcode.com/problems/intersection-of-two-arrays-ii/

三种方法:
  • 按照I的做法
  • 直接使用List,判断List是否contains即可(分析得效率最
  • 两个数组进行排序,使用两个指针求有序数组的交集
假设有k个交叉数,nums1长度n,nums2长度m,maxl=Math.max(n,m);
解法一(类似于I):
    leetcode上用时8ms,时间复杂度O(k*maxl);空间复杂度最大为O(m+n)。
[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. public class Solution {  
  2.     public int[] intersect(int[] nums1, int[] nums2) {  
  3.         if(nums1==null || nums2==null || nums1.length==0 || nums2.length==0)  
  4.             return new int[]{};  
  5.         Map<Integer,Integer> map=new HashMap<Integer,Integer>();  
  6.         List<Integer> list=new ArrayList<Integer>();  
  7.           
  8.         for(int i=0;i<nums1.length;i++){  
  9.             if(map.containsKey(nums1[i])){//containsKey时间复杂度最差为O(map.size());  
  10.                 map.put(nums1[i], map.get(nums1[i])+1);  
  11.             }else{  
  12.                 map.put(nums1[i], 1);  
  13.             }  
  14.         }  
  15.         for(int i=0;i<nums2.length;i++){  
  16.             if(map.containsKey(nums2[i])){  
  17.                 list.add(nums2[i]);  
  18.                 if(map.get(nums2[i])-1 <= 0){  
  19.                     map.remove(nums2[i]);  
  20.                 }else{  
  21.                     map.put(nums2[i], map.get(nums2[i])-1);  
  22.                 }  
  23.             }  
  24.         }  
  25.         int[]res=new int[list.size()];  
  26.         for(int i=0;i<res.length;i++){  
  27.             res[i]=list.get(i);  
  28.         }  
  29.         return res;  
  30.     }  
  31. }  
 

解法(直接使用List):
    用时16ms,时间复杂度高O(mn),空间复杂度最大为O(m+n)。最不合适的方法
[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. public class Solution {  
  2.     public int[] intersect(int[] nums1, int[] nums2) {  
  3.         List<Integer> temp=new ArrayList<Integer>();  
  4.         List<Integer> list=new ArrayList<Integer>();  
  5.           
  6.         for(int x:nums1){  
  7.             temp.add(x);  
  8.         }  
  9.         for(int x:nums2){  
  10.             if(temp.contains(x)){//看源码可知contains的复杂度是O(temp.size())  
  11.                 list.add(x);  
  12.                 temp.remove((Integer)x);  
  13.             }  
  14.         }  
  15.         int[]res=new int[list.size()];  
  16.         for(int i=0;i<res.length;i++){  
  17.             res[i]=list.get(i);  
  18.         }  
  19.         return res;  
  20.     }  
  21. }  

解法三(数组排序,两个指针):
    用时5ms,时间复杂度O(maxl*log(maxl)),空间复杂度为O(k)
[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. public class Solution {  
  2.     public int[] intersect(int[] nums1, int[] nums2) {  
  3.         Arrays.sort(nums1);//底层使用了快排,O(nlogn)  
  4.         Arrays.sort(nums2);  
  5.         List<Integer> list=new ArrayList<Integer>();  
  6.         for(int i=0,j=0;i<nums1.length&&j<nums2.length;){  
  7.             if(nums1[i]==nums2[j]){   
  8.                 list.add(nums1[i]);  
  9.                 i++;  
  10.                 j++;  
  11.             }  
  12.             else if(nums1[i]>nums2[j]){  
  13.                 j++;  
  14.             }else{  
  15.                 i++;  
  16.             }  
  17.         }  
  18.         int[]res=new int[list.size()];  
  19.         for(int i=0;i<res.length;i++){  
  20.             res[i]=list.get(i);  
  21.         }  
  22.         return res;  
  23.     }  
  24. }  

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

问题

  • What if the given array is already sorted? How would you optimize your algorithm?(第三种最好,且无须排序)
  • What if nums1's size is small compared to nums2's size? Which algorithm is better?(第一种比较好,nums1用hash表)
  • What if elements of nums2 are stored on disk, and the memory is limited such that you cannot load all elements into the memory at once?(如果能放下nums1就使用第一种,做成hash表;如果两个数组都放不下,就外部排序然后使用第三种)



0 0