小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
题目描述
给定两个数组,编写一个函数来计算它们的交集。
示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2,2]
示例 2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[4,9]
说明:
- 输出结果中每个元素出现的次数,应与元素在两个数组中出现次数的最小值一致。 我们可以不考虑输出结果的顺序。
进阶:
- 如果给定的数组已经排好序呢?你将如何优化你的算法?
- 如果 nums1 的大小比 nums2 小很多,哪种方法更优?
- 如果 nums2 的元素存储在磁盘上,内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?
题解
1.先对两个数组进行排序,然后双指针比较移动,如果相同就放入新数组.
public int[] intersect(int[] nums1, int[] nums2) {
// 1.先对两个数组进行排序
Arrays.sort(nums1);
Arrays.sort(nums2);
int left = 0;
int right = 0;
int k = 0;
int[] result = new int[nums1.length];
//2.使用双指针进行比较,如果相等, 将该元素放入数组,两个指针向后移动.如果不相等,稍小的指针向后移动
while (left < nums1.length && right < nums2.length) {
if (nums1[left] == nums2[right]) {
result[k] = nums1[left];
left++;
right++;
k ++;
}else if (nums1[left] < nums2[right]) {
left++;
}else {
right++;
}
}
return Arrays.copyOfRange(result,0,k);
}
map存储将第一个数组的所有元素和出现次数存储起来,然后第二数组遍历读取map.
通过存储次数,能够匹配到共同出现的次数
public static int[] intersect(int[] nums1, int[] nums2) {
Map<Integer, Integer> map = new HashMap<>();
int[] ints = new int[nums1.length];
Integer count = 0;
int k = 0;
// 先将第一个数组的元素和出现次数存储进来
for(int num : nums1) {
count = map.get(num);
if (null == count) {
map.put(num,1);
}else {
map.put(num,count+1);
}
}
// 第二个数组读取map,如果读取到,那么存储的次数-1,将元素放入新数组中.
for (int num : nums2) {
count = map.get(num);
if (null != count) {
ints[k] = num;
k ++;
count --;
// 当存储次数为0时,就去掉该元素,就读取不到了
if (0 == count) {
map.remove(num);
}else {
map.put(num,count);
}
}
}
return Arrays.copyOfRange(ints,0,k);
}