package leetcode.array;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
public class Intersect {
public static void main(String[] args) {
int[] nums1 = {4,9,5};
int[] nums2 = {9,4,9,8,4};
System.out.println(Arrays.toString(intersect_1(nums1, nums2)));
System.out.println(Arrays.toString(intersect_2(nums1, nums2)));
}
public static int[] intersect_1 (int[] nums1, int[] nums2) {
if (nums1.length > nums2.length) {
return intersect_1(nums2, nums1);
}
Map<Integer, Integer> map = new HashMap<>();
for (int num : nums1) {
int count = map.getOrDefault(num, 0) + 1;
map.put(num, count);
}
int[] intersect = new int[nums1.length];
int index = 0;
for (int num : nums2) {
int count = map.getOrDefault(num, 0);
if (count > 0) {
intersect[index++] = num;
count--;
if (count > 0) {
map.put(num, count);
} else {
map.remove(num);
}
}
}
return Arrays.copyOfRange(intersect, 0, index);
}
public static int[] intersect_2 (int[] nums1, int[] nums2) {
Arrays.sort(nums1);
Arrays.sort(nums2);
int len1 = nums1.length;
int len2 = nums2.length;
int index1 = 0;
int index2 = 0;
int index = 0;
int[] intersect = new int[Math.min(len1, len2)];
while (index1 < len1 && index2 < len2) {
if (nums1[index1] < nums2[index2]) {
index1++;
} else if (nums1[index1] > nums2[index2]) {
index2++;
} else {
intersect[index] = nums1[index1];
index++;
index1++;
index2++;
}
}
return Arrays.copyOfRange(intersect, 0, index);
}
}
复杂度分析
时间复杂度:O(mlogm+nlogn),其中 m 和 n分别是两个数组的长度。对两个数组进行排序的时间复杂度是 O(mlogm+nlogn),遍历两个数组的时间复杂度是O(m+n),因此总时间复杂度是 O(mlogm+nlogn)。
空间复杂度:O(min(m,n)),其中 m 和 n 分别是两个数组的长度。为返回值创建一个数组 intersection,其长度为较短的数组的长度。不过在 C++ 中,我们可以直接创建一个 vector,不需要把答案临时存放在一个额外的数组中,所以这种实现的空间复杂度为 O(1)。
结语
如果 nums 2的元素存储在磁盘上,磁盘内存是有限的,并且你不能一次加载所有的元素到内存中。那么就无法高效地对 nums 2进行排序,因此推荐使用方法一而不是方法二。在方法一中,nums 2只关系到查询操作,因此每次读取 nums 2中的一部分数据,并进行处理即可。
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/intersection-of-two-arrays-ii/solution/liang-ge-shu-zu-de-jiao-ji-ii-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。