给你两个整数数组 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 的元素存储在磁盘上,内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?
Related Topics 数组 哈希表 双指针 二分查找 排序 985 0
import java.util.*;
//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
public int[] intersect(int[] nums1, int[] nums2) {
int[] result = new int[Math.min(nums1.length, nums2.length)];
// 排序 1 2
Arrays.sort(nums1);
Arrays.sort(nums2);
int resultIdx = 0;
// 遍历nums1
for (int i = 0; i < nums1.length;) {
int i1 = nums1[i];
// 二分查找nums2中包含元素i1的个数
int count2 = getCountFromSortedArrayByValue(i1, nums2);
// 统计nums1中当前值i1的数量
int count1 = getCountFromSortedArrayByIdx(i, nums1);
// count2 == 0 do nothing skip current value
if (count2 > 0) {
// 取交集即取最小值
int min = Math.min(count1, count2);
// 添加min次到返回的数组中
for (int i2 = 0; i2 < min; i2++) {
result[resultIdx++] = i1;
}
}
// 跳下标,相同的值不需要再计算
i += count1;
}
return Arrays.copyOfRange(result, 0, resultIdx);
}
private int getCountFromSortedArrayByValue(int value, int[] array) {
int i = Arrays.binarySearch(array, value);
if (i < 0) return 0;
// 找到随机一处的位置,因为nums2是排好序的,所以从i的左右开始找和nums2[i]相同的值,l,r l-r+1 就可以知道一共有多个相同的元素
return getCountFromSortedArrayByIdx(i, array);
}
private int getCountFromSortedArrayByIdx(int idx, int[] nums2) {
int l = idx - 1, r = idx + 1;
boolean flag = true;
while (flag) {
flag = false;
if (l >= 0 && nums2[l] == nums2[idx]) {
flag = true;
l--;
}
if (r < nums2.length && nums2[r] == nums2[idx]) {
flag = true;
r++;
}
}
return r - l - 1;
}
}