三、两个数组的交集
题目:
给定两个数组 nums1 和 nums2 ,返回 它们的 交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。
示例1:
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]
示例2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[9,4]
解释:[4,9] 也是可通过的
提示:
- 1 <= nums1.length, nums2.length <= 1000
- 0 <= nums1[i], nums2[i] <= 1000
解题思路分析
如果哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费!
本题可以选择使用HashSet或者Hash数组;这里能使用数组是因为题目中对数值范围做了限制。
思路:
将第一个数组中的所有元素经过处理,放进一个哈希表中(转变为哈希表的形式存数组1中的所有元素);
接着,再遍历数组2中每个元素,去查询哈希表中是否出现过该元素;
如果出现过就放入result集合中,最后返回result集合。
HashSet解决:
HashSet具体内容可以参考这篇文章: https://blog.youkuaiyun.com/weixin_43970743/article/details/134224862
代码讲解:
//定义一个HashSet,用来存放数组1
Set<Integer> set1 = new HashSet<>();
//再定义一个HashSet,用来存放交集(result集合)
Set<Integer> resSet = new HashSet<>();
//遍历数组1,把其中所有元素放进set1中
for(int i : nums1) {
set1.add(i);
}
//遍历数组2,判断数组2中的每个元素是否存在于哈希表中
for(int i : nums2) {
//如果数组2中的元素在set1中存在,就说明是交集元素,放入结果集合中
if(set1.contains(i)) {
resSet.add(i);
}
}
//将结果集合转换为数组后返回
return resSet.stream().mapToInt(x -> x).toArray();

数组解决:
题目中说数值都在1000以内,那么定义一个比1000稍大一点的数组即可(防止越界)。
遍历数组1,将其中的元素在哈希数组中所在位置都赋值为1,这样就记录了出现的元素了。(类似上一小节的处理方法)
遍历数组2,如果该元素在哈希数组中所在位置的值已经为1,代表该元素在数组1中出现过了,将该元素放入result集合中。
代码讲解:
//先定义一个Hash数组(数组初始值默认都为0),分别记录数组1和2中出现的元素
int[] hash1 = new int[1002];
//再定义一个Hash数组,用来遍历并记录数组2
int[] hash2 = new int[1002];
//遍历数组1,在哈希数组1中进行记录
for (int i : nums1) {
hash1[i] = 1;
}
//遍历数组2,在哈希数组2中进行记录
for (int i : nums2) {
hash2[i] = 1;
}
//定义ArrayList,存放交集元素
List<Integer> resList = new ArrayList<>();
//遍历两个数组,将交集元素放入resList中
for(int i = 0; i < 1002; i++) {
if(hash1[i] == 1 && hash2[i] == 1) { //去重,避免重复添加相同元素进resList
resList.add(i);
}
}
//定义result数组,将交集元素放入数组中并返回
int[] result = new int[resList.size()];
int index = 0;
for(int i : resList) {
result[index++] = i;
}
return result;
说明:
这里为什么不直接定义为一个result数组装元素然后返回?
因为直接用预先定义好的数组的话,长度不一定对,会返回如下图所示内容:也就是会返回数组中所有元素。
所以只有先拿出来所有交集元素,再根据元素个数定义大小相等的数组来返回结果。

注意:
那有同学可能问了,遇到哈希问题我直接都用set不就得了,用什么数组啊?
直接使用set 不仅占用空间比数组大,而且速度要比数组慢,set把数值映射到key上都要做hash计算的。
不要小瞧 这个耗时,在数据量大的情况,差距是很明显的。
题解:
HashSet解法:

哈希数组解法:

本文介绍了如何使用HashSet和哈希数组来解决LeetCode349题,即找出两个数组的交集。两种方法对比了空间和时间效率,并强调了在数值范围受限的情况下使用数组的可行性。





