一、题目
给定两个数组,编写一个函数来计算它们的交集。
示例 1:
输入: nums1 = [1,2,2,1], nums2 = [2,2]
输出: [2,2]
示例 2:
输入: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出: [4,9]
说明:
- 输出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致。
- 我们可以不考虑输出结果的顺序。
二、思路及代码实现
思路一:哈希映射
- 统计一个数组中每个数字出现的次数,存放在 HashMap 中(以 值-出现次数 的形式存储);
- 遍历另一个数组,查找每个数字是否存在哈希表中,如果存在,将该数字添加至结果集,并把 hashMap 中对应的次数减一;如果不存在,则检查下一个数字。
代码实现(一):
class Solution {
public int[] intersect(int[] nums1, int[] nums2) {
Map<Integer, Integer> map = new HashMap<>();
for(int i : nums1){
if(map.containsKey(i))
map.put(i, map.get(i) + 1);
else
map.put(i, 1);
}
int k = 0;
for(int n : nums2){
if(map.containsKey(n) && map.get(n) > 0){
nums1[k++] = n;
map.put(n, map.get(n) - 1);
}
}
return Arrays.copyOfRange(nums1, 0, k);
}
}
利用 Map 的 getOrDefault() 方法,可以简化代码。
Map 的 getOrDefault(key, defaultValue) 方法:
- 括号中的第一个参数是你要取的 key,第二个参数是你指定的默认值;
- 意思是:如果 map 中存在 key 这个键,那就返回这个键对应的值;不存在这个 key,则返回默认值。
举个例子:
Map<Integer, Integer> map = new HashMap<>();
map.put(1, 11);
// 存在 1 这个键,返回其对应的值 11
System.out.println(map.getOrDefault(1, 22)); // 11
// 不存在 3 这个键,返回默认值 33
System.out.println(map.getOrDefault(3, 33)); // 33
// 需要注意的是:
// 只要存在这个 key,就返回它对应的值,即使这个值为 null;不存在这个 key 时,才返回默认值。
map.put(4, null);
// 这里打印的是 null,而不是 22
System.out.println(map.getOrDefault(4, 22));
简化代码如下:
class Solution {
public int[] intersect(int[] nums1, int[] nums2) {
Map<Integer, Integer> map = new HashMap<>();
for(int i : nums1){
int count = map.getOrDefault(i, 0);
map.put(i, count + 1);
}
int k = 0;
for(int n : nums2){
int t = map.getOrDefault(n, 0);
if(t > 0){
nums1[k++] = n;
map.put(n, t - 1);
}
}
return Arrays.copyOfRange(nums1, 0, k);
}
}
思路二:排序
分别对两个数组进行排序,然后逐个比对两个数组的元素,找到重复元素。
- 对两个数组排序;
- 初始化三个指针 i = 0、j = 0、k = 0,i 和 j 指向两个数组,k 用来记录重复元素的个数;
- 如果 nums1[i]=nums2[j]nums1[i] = nums2[j]nums1[i]=nums2[j],将该元素拷贝到 nums1[k]nums1[k]nums1[k],然后 i++,j++,k++;
- 如果 nums1[i]>nums2[j]nums1[i] > nums2[j]nums1[i]>nums2[j],j++;
- 如果 nums1[i]<nums2[j]nums1[i] < nums2[j]nums1[i]<nums2[j],i++。
- 最后返回 nums1 的前 k 个元素。
代码如下:
class Solution {
public int[] intersect(int[] nums1, int[] nums2){
Arrays.sort(nums1);
Arrays.sort(nums2);
int i = 0, j = 0, k = 0;
while(i < nums1.length && j < nums2.length){
if(nums1[i] == nums2[j]){
nums1[k] = nums2[j];
i++;
j++;
k++;
}else if(nums1[i] > nums2[j]){
j++;
}else if(nums1[i] < nums2[j]){
i++;
}
}
return Arrays.copyOfRange(nums1, 0, k);
}
}
本文介绍了两种计算两个数组交集的有效方法:哈希映射和排序。哈希映射通过统计一个数组中每个数字出现的次数,使用HashMap存储,再遍历另一个数组,查找并减少次数来获取交集。排序方法则是先对两个数组进行排序,然后通过比较和移动指针的方式找出重复元素。
1011

被折叠的 条评论
为什么被折叠?



