350. 两个数组的交集 II
难度简单640收藏分享切换为英文接收动态反馈
给你两个整数数组 nums1
和 nums2
,请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致(如果出现次数不一致,则考虑取较小值)。可以不考虑输出结果的顺序。
示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2,2]
示例 2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[4,9]
提示:
-
1 <= nums1.length, nums2.length <= 1000
-
0 <= nums1[i], nums2[i] <= 1000
进阶:
- 如果给定的数组已经排好序呢?你将如何优化你的算法?
- 如果
nums1
的大小比 nums2
小,哪种方法更优? - 如果
nums2
的元素存储在磁盘上,内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?
二、方法一
哈希表,先存储数组长度短,减少空间,然后对第一个数组进行计数存储,然后遍历第二个数组获取交集,拿出来一个次数减一,最后便得到交集
class Solution {
public int[] intersect(int[] nums1, int[] nums2) {
if (nums1 == null || nums1.length == 0 || nums2 == null || nums2.length == 0) {
return new int[0];
}
if (nums1.length > nums2.length) {
intersect(nums2, nums1);
}
Map<Integer, Integer> map = new HashMap<>();
for (int num : nums1) {
map.put(num, map.getOrDefault(num, 0) + 1);
}
int index = 0;
int[] arr = new int[nums1.length];
for (int num : nums2) {
int cur = map.getOrDefault(num, 0);
if (cur > 0) {
arr[index++] = num;
cur--;
if (cur > 0) {
map.put(num, cur);
} else {
map.remove(num);
}
}
}
return Arrays.copyOfRange(arr, 0, index);
}
}
- 时间复杂度:O(m+n),其中 m 和 n 分别是两个数组的长度。需要遍历两个数组并对哈希表进行操作,哈希表操作的时间复杂度是 O(1),因此总时间复杂度与两个数组的长度和呈线性关系。
- 空间复杂度:O(min(m,n)),其中 m 和 n 分别是两个数组的长度。对较短的数组进行哈希表的操作,哈希表的大小不会超过较短的数组的长度。为返回值创建一个数组 arr,其长度为较短的数组的长度。
三、方法二
先对两个数组进行排序,然后定义两个指针,如果当前两个数不相等,则向右移动较小的指针,如果相等则添加元素,并同时右移两个指针
class Solution {
public int[] intersect(int[] nums1, int[] nums2) {
if (nums1 == null || nums1.length == 0 || nums2 == null || nums2.length == 0) {
return new int[0];
}
int[] res = new int[Math.min(nums1.length, nums2.length)];
int index = 0;
int l = 0;
int r = 0;
Arrays.sort(nums1);
Arrays.sort(nums2);
while (l < nums1.length && r < nums2.length) {
if (nums1[l] > nums2[r]) {
r++;
} else if (nums1[l] < nums2[r]) {
l++;
} else {
res[index++] = nums1[l];
l++;
r++;
}
}
return Arrays.copyOfRange(res, 0, index);
}
}
- 时间复杂度:O(mlogm+nlogn),其中 m 和 n 分别是两个数组的长度。对两个数组进行排序的时间复杂度是 O*(mlogm+nlogn),遍历两个数组的时间复杂度是 O(m+n),因此总时间复杂度是 O(mlogm+nlog*n)。
- 空间复杂度:O(min(m,n)),其中 m*和 n分别是两个数组的长度。为返回值创建一个数组 res,其长度为较短的数组的长度。