【哈希表第二篇】第349题. 取两个数组的交集

106 阅读2分钟

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

「说明:」
输出结果中的每个元素一定是唯一的。
我们可以不考虑输出结果的顺序。

遇到题目,先想一想用什么来存储这个输出结果,如果用数组,可以保证顺序,但是要去重
还是用set吧,不用去重,而且和题目要求的一样,就是不用保证顺序的

思路
这道题目,主要要学会使用一种哈希数据结构:unordered_set,这个数据结构可以解决很多类似的问题。

注意题目特意说明:「输出结果中的每个元素一定是唯一的,也就是说输出的结果的去重的, 同时可以不考虑输出结果的顺序」

这道题用暴力的解法时间复杂度是O(n^2),那来看看使用哈希法进一步优化。

可以发现,貌似用数组做哈希表可以解决这道题目,把nums1的元素,映射到哈希数组的下表上,然后在遍历nums2的时候,判断是否出现过就可以了。

但是要注意,「使用数据来做哈希的题目,都限制了数值的大小,例如哈希表:可以拿数组当哈希表来用,但哈希值不要太大题目中只有小写字母,或者数值大小在[0- 10000] 之内等等。」

而这道题目没有限制数值的大小,就无法使用数组来做哈希表了。

「而且如果哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费。」

此时就要使用另一种结构体了,set,HashSet;

思路如图所示:

图片
哈希法使用unordered_set
C++代码

import java.util.*;
class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
       Set<Integer> parentSet=new HashSet<>(); 
       for(int num:nums1)
          parentSet.add(num);
       Set<Integer> childset=new HashSet<>();
       for (int i=0;i<nums2.length;i++){
           if(parentSet.contains(nums2[i]))   // 其实这也就是两个for循环,只是内循环变为set罢了
              childset.add(nums2[i]);  // 里面是不重复的交集 
       }
       // 从set变成数组
       int index=0;
       int[] res=new int[childset.size()];
       for (int num:childset)
          res[index++]=num;   // set没有get方法,就这样foreach迭代取出即可
       return res;
    }
}

核心:就是两个for循环,然后内层循环变为for循环罢了
得到的childset变为res数组