LeetCode第350题:两个数组的交集II

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

示例 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 的元素存储在磁盘上,内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?(采用第一种,依次加载)

方法一:

public int[] intersect(int[] nums1, int[] nums2) {
        //方法1:哈希表,将小的数组装进哈希表,key为值,value为出现的次数
        //遍历大的数组,每次去查哈希表,如果有,放入新的数组,将value-1,如果此时value>0,重新放入map
        //时间复杂度:O(m+n) 空间复杂度O(min(m,n))

        //nums1为小数组
        if (nums1.length > nums2.length) {
            return intersect(nums2, nums1);
        }

        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < nums1.length; i++) {
            //如果有该值,获取该值并加1,如果没有,设为1
            int count = map.getOrDefault(nums1[i], 0) + 1;
            map.put(nums1[i], count);
        }

        //结果数组
        int[] num = new int[nums1.length];
        int index = 0;
        for (int i = 0; i < nums2.length; i++) {
            //获取value值,如果没有则为0
            int count = map.getOrDefault(nums2[i], 0);
            //如果有value
            if (count > 0) {
                //放入数组,同时将count-1
                num[index++] = nums2[i];
                count--;
                //如果count还大于0,继续放回map
                if (count > 0) {
                    map.put(nums2[i], count);
                } else {
                    //否则移除
                    map.remove(nums2[i]);
                }
            }
        }
        //拷贝数组
        return Arrays.copyOfRange(num, 0, index);
    }

方法二:

public int[] intersect(int[] nums1, int[] nums2) {
        //方法2:先对数组进行排序,然后用两个指针指向起始位置,比较两个指针指向的数,如果不一样,将小的指针后移,如果相等,放入数组中
        //时间复杂度O(mlogm+nlogn) 空间复杂度O(min(m,n))
        Arrays.sort(nums1);
        Arrays.sort(nums2);
        int length1 = nums1.length;
        int length2 = nums2.length;
        int[] num = new int[Math.min(length1,length2)];
        int index = 0,index1 = 0,index2 = 0;
        //终止条件为有一个指针超出数组范围
        while (index1 < length1 && index2 < length2){
            if (nums1[index1] < nums2[index2]){
                index1++;
            }else if (nums1[index1] > nums2[index2]){
                index2++;
            }else {
                num[index++] = nums1[index1];
                index1++;
                index2++;
            }
        }
        return Arrays.copyOfRange(num,0,index);
    }
posted @ 2020-08-17 12:07  马晟  阅读(98)  评论(0编辑  收藏  举报