350. Intersection of Two Arrays II

题目描述

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

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

注意:

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

跟进:

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

我的解法——哈希计数(AC)

  • 哈希计数
  • 时间空间复杂度均为O(n)。
  • Beat92%
class Solution:
    def intersect(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: List[int]
        """
        dic1 = {}
        dic2 = {}
        
        for now in nums1:
            if(now in dic1):
                dic1[now] += 1
            else:
                dic1[now] = 1
        
        for now in nums2:
            if(now in dic2):
                dic2[now] += 1
            else:
                dic2[now] = 1
        res = []
        for now in dic2:
            if(now in dic1):
                res += [now] * min(dic1[now],dic2[now])
        return res

#最优解法——改进哈希计数

  • 哈希计数,只哈希一个数组。
  • 复杂度:O(n)
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;  
    }  
}  

其他解法——排序再查找

  • 首先将两个数组从小到大排序,后分别用两个指针指向两个数组开头比较大小,将小的数组指针后移。直至两指针指向数字相等时考虑将数字放入res中。
  • 复杂度:O(nlogn)
public class Solution {
    public int[] intersect(int[] nums1, int[] nums2) {
        Arrays.sort(nums1);
        Arrays.sort(nums2);
        List<Integer> list = new ArrayList<>();
        int i=0, j=0;
        while (i<nums1.length && j<nums2.length) {
            if (nums1[i] == nums2[j]) { list.add(nums1[i]); i++; j++; }
            else if (nums1[i] < nums2[j]) i++;
            else j++;
        }
        int[] result = new int[list.size()];
        for(int k=0; k<list.size(); k++) result[k] = list.get(k);
        return result;
    }
}

参考答案

  • https://zhuanlan.zhihu.com/p/32786833
  • http://bookshadow.com/weblog/2016/05/21/leetcode-intersection-of-two-arrays-ii/