前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >两个数组的交集 II

两个数组的交集 II

作者头像
木瓜煲鸡脚
发布2020-09-29 10:40:09
9300
发布2020-09-29 10:40:09
举报
文章被收录于专栏:Jasper小笔记Jasper小笔记

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

示例 1:

代码语言:javascript
复制
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2,2]

示例 2:

代码语言:javascript
复制
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[4,9]

说明:

  • 输出结果中每个元素出现的次数,应与元素在两个数组中出现次数的最小值一致。
  • 我们可以不考虑输出结果的顺序。

进阶:

  • 如果给定的数组已经排好序呢?你将如何优化你的算法?
  • 如果 nums1 的大小比 nums2 小很多,哪种方法更优?
  • 如果 nums2 的元素存储在磁盘上,内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?
题目信息

输入:两个整数数组

输出:交集数组

额外:不考虑顺序

思考

就相当于是数学集合求交集,很容易想到的就是双指针扫描比较判断是否存入结果。对于这样的方式就选择先排序再比较。

代码语言:javascript
复制
nums1 = [4,5,9], nums2 = [4,4,8,9,9]

nums1[0] == nums2[0] true 存4 
nums1[1] == nums2[1] false且> nums1指针不变
nums1[1] == nums2[2] false且< nums2指针不变
nums1[2] == nums2[2] false且> nums1指针不变
nums1[2] == nums2[3] true 存9 
nums1已遍历完毕结束结果为[4,9]
代码语言:javascript
复制
//方式一
public int[] intersect(int[] nums1, int[] nums2) {
    //排序
  Arrays.sort(nums1);
    Arrays.sort(nums2);
    //两个指针
    int i = 0;
    int j = 0;
    //结果数组及其存储下标
    int[] result = new int[nums1.length];
    int index = 0;
    while(i<nums1.length && j<nums2.length){
      if(nums1[i] == nums2[j]){
            result[index] = nums1[i];
            i++;
            j++;
            index++;
        }else if(nums1[i] > nums2[j]){
            j++;
        }else{
            i++;
        }
    }
    return Arrays.copyOfRange(result,0,index);
}

空间复杂度O(n),时间复杂度O(nlogn+mlogm)。

和前面写过的几道题一样都是除了双指针扫描之外还可以使用hash表来解决并且时间复杂度要比扫描比较的方式优。这里找到相同的值同样用hash表记录然后另一个再到hash表里比对。这样时间复杂度为O(n+m)

代码语言:javascript
复制
public int[] intersect(int[] nums1, int[] nums2) {
    //新建结果数组,index指向存储位置
    int[] result = new int[nums1.length];
    int index = 0;
    //新建hashmap统计一个数组的数字记录
    Map<Integer,Integer> map = new HashMap();
    for(int num1 : nums1){
        int count = map.getOrDefault(num1,0)+1;
        map.put(num1,count);
    }
    //遍历另外数组与hashmap比对,相同的取出存入
    for(int num2 : nums2){
    int count = map.getOrDefault(num2, 0);
            if (count > 0) {
                result[index] = num2;
                index++;
                count--;
                if (count > 0) {
                    map.put(num2, count);
                } else {
                    map.remove(num2);
                }
            }
    }
    return Arrays.copyOfRange(result,0,index);
}
总结

两种方法一种两个数组排序使用双指针同步比较,第二种先将一个数组统计到hash表另一个再对照查找存不存在,对于进阶里面的三条第一条是已经排好序那么遍历直接比较即可时间复杂度O(n+m),如果两数组长度差距大的话首先空间优化创建的result数组用小的那个容量创建其他就是对使用hash表的方式有影响用短的数组记录。最后一种nums2过大就是内存不过并不能直接全部排序比较,那就使用hash表的方式,hash表统计完nums1然后nums2只需要一个一个对照即可不需要全部纳入。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-09-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 IT那个小笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题目信息
  • 思考
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档