两个数组的交集
Posted KeepGoing
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了两个数组的交集相关的知识,希望对你有一定的参考价值。
1.问题描述
给定两个数组,编写一个函数来计算它们的交集。
示例 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 的元素存储在磁盘上,内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?
2.求解
哈希表
- 比较两个数组的长度,遍历较大的数组,将其存入元素作为键,出现次数作为值,存入hash表中
- 遍历另一个较小的数组,若它的元素在哈希表中出现,即把其存入新的数组中,并且将出现次数减一,重新存入哈希表中
代码如下
/*
* 执行用时:4 ms, 在所有 Java 提交中击败了53.75% 的用户
* 内存消耗:38.9 MB, 在所有 Java 提交中击败了51.97% 的用户
* */
public int[] intersect(int[] nums1, int[] nums2) {
if(nums2.length > nums1.length){
return intersect(nums2,nums1);
}
Map<Integer, Integer> map = new HashMap<>();
for(int num : nums1){
map.merge(num, 1, (oldX, newX) -> oldX += 1);
}
int[] res = new int[nums1.length];
int index = 0;
for(int num : nums2){
int count = map.getOrDefault(num, 0);
if(count > 0){
res[index] = num;
index ++;
count --;
}
map.put(num, count);
}
return Arrays.copyOfRange(res, 0, index);
}
- 时间复杂度:O(n),n为两数组大小之和
- 空间复杂度:O(n),n为较小数组元素个数
ps:对int[]数组的复制操作
-
System.arraycopy(arr, copied, start, end);
-
Arrays.copyOfRange(intersection, 0, index);
区别:Arrays.copyOf()不仅仅只是拷贝数组中的元素,在拷贝元素时,会创建一个新的数组对象。而System.arrayCopy只拷贝已经存在数组元素。
? Array.copyOf()底层是调用的System.arrayCopy(new了一个数组对象,复制后返回)
排序 + 双指针
代码如下
/*
*执行用时:1 ms, 在所有 Java 提交中击败了100.00% 的用户
*内存消耗:38.8 MB, 在所有 Java 提交中击败了75.93% 的用户
*/
public int[] intersect(int[] nums1, int[] nums2) {
Arrays.sort(nums1);
Arrays.sort(nums2);
int m = nums1.length;
int n = nums2.length;
int[] res = new int[m + n];
int length = 0;
int i = 0, j = 0;
while(i < m && j < n){
if(nums1[i] == nums2[j]){
res[length] = nums1[i];
length++;
i++;
j++;
}else if(nums1[i] < nums2[j]){
i++;
}else{
j++;
}
}
return Arrays.copyOfRange(res, 0, length);
}
- 时间复杂度:O(mlog?m+nlog?n),排序的时间复杂度是O(mlog?m+nlog?n),遍历的时间复杂度是O(m + n),所以总的时间复杂度是O(mlogm + nlogn)
- 空间复杂度:O(m +n)
ps:这里新建数组可以改成如下。
? int[] res = new int[Math.min(m,n)]
,这样空间复杂度就变成了O(min(m,n))
以上是关于两个数组的交集的主要内容,如果未能解决你的问题,请参考以下文章