题目描述
给定两个数组,编写一个函数来计算它们的交集。
示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]
示例 2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[9,4]
分析和实现
对于这个问题,要求的结果是两个数组的交集,也就是两者都有的元素。那么,很自然的思路就是对两个数组进行统计,然后查看两者之间的相同元素。
Map + Set
在具体实现时,我用 map 对第一个数组进行统计,用 set 来保存两个数组相同的元素。因为 map 对检索元素上比较友好。
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
Map<Integer, Integer> numsMap = new HashMap<>();
for(int i=0;i<nums1.length;i++){
numsMap.put(nums1[i], numsMap.getOrDefault(nums1[i], 0) +1);
}
Set<Integer> resultSet = new HashSet<Integer>();
for(int i=0;i<nums2.length;i++){
if(numsMap.containsKey(nums2[i])){
resultSet.add(nums2[i]);
}
}
int[] result = new int[resultSet.size()];
int count = 0;
for(int re: resultSet){
result[count] = re;
count++;
}
return result;
}
}
效果:
排序 + 双指针
官方题解中还给出了另一种方法:排序+双指针法。这种方法首先将两个数组进行排序,然后使用两个指针分别指向了数组的开头进行比较,如果不相等,数值较小的指针移动,反之进行记录。代码如下:
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
Arrays.sort(nums1);
Arrays.sort(nums2);
int length1 = nums1.length, length2 = nums2.length;
int[] intersection = new int[length1 + length2];
int index = 0, index1 = 0, index2 = 0;
while (index1 < length1 && index2 < length2) {
int num1 = nums1[index1], num2 = nums2[index2];
if (num1 == num2) {
// 保证加入元素的唯一性
if (index == 0 || num1 != intersection[index - 1]) {
intersection[index++] = num1;
}
index1++;
index2++;
} else if (num1 < num2) {
index1++;
} else {
index2++;
}
}
return Arrays.copyOfRange(intersection, 0, index);
}
}
这种思路的时间复杂度和空间复杂度相较于上面会更好一些。
效果: