02.算法学习之两个数组的交集(两个数组的交集 java实现)

题目:给定两个数组,编写一个函数来计算它们的交集。

说明:

1.输出结果中每个元素出现的次数,应与元素在两个数组中出现次数的最小值一致

2.不考虑输出结果顺序

示例:

输入:num1=[1,2,2,1] , nums2=[2,2]

输出:[2, 2]


思路:对于我来说,这样类似的题,我上来就是一顿双重For循环遍历, 哈哈。 不过在遍历的时候,还要注意num2层的数据不能重复匹配。 加入nums2=[2] ,那么就只能匹配num1中的一个2,而不能匹配两个,所以要注意维护下num2中被匹配的元素,你可以使用一个set来记录相关下标。

Set<Integer> set = new HashSet<>();
for (int i = 0; i < nums1.length; i++) {
      for (int j = 0; j < nums2.length; j++) {
       if (nums1[i] == nums2[j]) {
           if (!set.contains(j)) {
               set.add(j);
               break;
           }
           continue;
        }
     }
}
int size = set.size();
int[] a = new int[size];
for (int n : set) {
      a[--size] = nums2[n];
}
return a;

虽然上面双重For循环可以解决问题,但是我们还是要思考下更优解。

题目多思考几次就可以看出我们不用管结果顺序,只要求出元素在两个数组中出现的公共次数就行了,那么我们可以先统计NUM1中出现的次数,在遍历num2中出现的次数即可。 空间换时间,增加一个Map结构来存num和其出现次数的映射。

public static int[] intersect3(int[] nums1, int[] nums2) {
        if(nums1.length > nums2.length){
            //减少空间复杂度,Map存储短的数组
            return intersect3(nums2, nums1);
        }
        Map<Integer, Integer> map = new HashMap<>();
        // 遍历构建num1 Map
        for (int n : nums1){
            int count = map.getOrDefault(n, 0) + 1;
            map.put(n, count);
        }
        int[] res = new int[nums1.length];
        int index = 0;
        //根据map和nums2 构建res[]
        for (int num : nums2){
            int count  = map.getOrDefault(num , 0);
            if(count > 0){
                res[index++] = num;
                count--;
                if(count > 0){
                    map.put(num, count);
                }else {
                    map.remove(num);
                }
            }
        }
        return Arrays.copyOfRange(res, 0, index);
    }


每次在使用暴力解法后(解后圣如佛),还是得思考下更优解是什么。

这里有一个进阶题,若num1和num2是已经排好序的数组,那么更优解是什么?

下篇解答 : )

原文链接:,转发请注明来源!