题意:给定两个数组,编写一个函数来计算它们的交集。
「说明:」
输出结果中的每个元素一定是唯一的。
我们可以不考虑输出结果的顺序。
遇到题目,先想一想用什么来存储这个输出结果,如果用数组,可以保证顺序,但是要去重
还是用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数组