给定两个数组,编写一个函数来计算它们的交集。
map.getOrDefault(key, default): 从map中取出key对应的value,map中没有这个key的话返回default
Arrays.copyOfRange( T[ ] original,int from,int to ): 将一个原始的数组original,从下标from开始复制,复制到上标to,生成一个新的数组。
注意这里包括下标from,不包括上标to。
1、哈希表
交集最大等于短的那个数组,所以先遍历短数组,将其元素的值作为key,出现的次数作为value纪录进哈希表,作为一个元素池,然后遍历长数组,当池子里有当前元素就把这个元素从池子里取出来一个,最终构成交集
public static int[] intersect(int[] nums1, int[] nums2) {
// 遍历短的记录map,省点时间
if (nums1.length > nums2.length) {
return intersect(nums2, nums1);
}
Map<Integer, Integer> map = new HashMap<>();
for (int num : nums1) {
int count = map.getOrDefault(num, 0) + 1;
map.put(num, count);
}
// 交集大小不会超过最短的的数组
int[] result = new int[nums1.length];
int index = 0;
// 遍历长数组
for (int num : nums2) {
int count = map.getOrDefault(num, 0);
if (count > 0) {
result[index++] = num;
count--;
// 判断短数组是否还有该值
if (count > 0) {
map.put(num, count);
} else {
map.remove(num);
}
}
}
return Arrays.copyOfRange(result, 0, index);
}
2、双指针
当两个数组都有序的时候可以使用双指针求解
public int[] intersect(int[] nums1, int[] nums2) {
Arrays.sort(nums1);
Arrays.sort(nums2);
int length1 = nums1.length, length2 = nums2.length;
// 定位用的指针
int index1=0,index2=0,index=0;
int[] result = new int[Math.max(length1, length2)];
while (index1 < length1 && index2 < length2) {
// 因为是升序数组,谁小谁后移,相等都后移并记录值
if (nums1[index1] < nums2[index2]) {
index1++;
} else if (nums1[index1] > nums2[index2]) {
index2++;
} else {
result[index++] = nums1[index1];
index1++;
index2++;
}
}
return Arrays.copyOfRange(result, 0, index);
}